commit c8758ecfdcc73569f5b863395474db4076c30d74 Author: Frank.R.Wu Date: Tue Jun 15 19:56:39 2021 +0800 feat: init; from commit c3adcb2e6bc94b46f4f34c03bc62abcce6c7e1a0 of BDContract diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a09c56d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.idea diff --git a/BlockIndexer.html b/BlockIndexer.html new file mode 100644 index 0000000..97b6ff0 --- /dev/null +++ b/BlockIndexer.html @@ -0,0 +1,471 @@ + + + + + 数瑞通用区块链索引工具 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ +
+
+
+
+
+
+
向导栏
+
+
+ 内容页 +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
这里是个表格
+
+
+ 内容页 +
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
这里是个表格
+
+
+ 内容页 +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
这里是个表格
+
+
+ 内容页 +
+
+
+
+
+
+
+ + +
+ +
+
+
+
+
+
+
节点配置
+
+
+
+
+ 节点名称 +
+ +
+ +
+
+
+
+
+
+ PeerID +
+ +
+
+
+
+
+ YJS路径 +
+ +
+ +
+
+
+
+
+
+ 加入网络 +
+ +
+ +
+
+
+
+
+
+ 数链节点 +
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
可信执行集群列表
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
Licence配置
+
+
+
+
+ Licence +
+ +
+
+
+
+ Licence过期时间 +
+
+
+
+ + + + +
+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/NodePortal.html b/NodePortal.html new file mode 100644 index 0000000..0f2a21b --- /dev/null +++ b/NodePortal.html @@ -0,0 +1,1259 @@ + + + + + 数瑞智能合约节点管理中心 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ +
+
+
+
+
+
+
用户情况
+ +
+
+ Loading... +
+
+
+
+
+
+
+
+
用户活跃统计
+ +
+
+
+ Loading... +
+
+
+ +
+
+
+
+ + +
+
+
+
+
授权用户管理
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
未授权用户管理
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+ +
+ +
+
+ +
+
+
+
+
+
+
+ +
+ + +
+ +
+
+ +
+
+ +
+
+ + + + + + +
+ + +
+
+
+
+ + + +
+ +
+
+
+
+
+
+ + +
+
+
+
+
+
+ 返回结果显示 +

+ +
+
+
+
+ + +
+ +
+
+
+ + +
+ + +
+
+ +
+
+
+
+
合约实例状态
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
各类合约实例调用次数
+
+
+
+ Loading... +
+
+
+
+
+
+
+ +
+
+
+
+
合约实例列表
+
+
+ Loading... +
+
+
+ +
+
+
+ +
+
+
+
+
合约进程列表
+
+
+ Loading... +
+
+
+ +
+
+
+
+
+
+
+
实例详情
+
+
+
+
+ +
+
+ +
+ + + + + +
+
+
+
实例调用
+
+
+ +
+
+ 参数 +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+
+
+ 执行状态: +
+
+ 执行ID: +
+
+ 执行时间: +
+ +
+
+
+
权限管理
+
+
+
+
+
+
+ 当前合约权限 +
+
+
    +
+
+
+
+
+
+
+
状态管理
+
+
+
+
+ +
+
+ +
+
+ 选择镜像文件: + +
+ +
+ +
+
+ +
+
+
+
+
+
+ 结果: +
+ +
+
+
+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+
+
+
各类平台操作百分比
+
+
+ 时间 +
+ +
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
各类合约操作百分比
+
+
+ 时间 +
+ +
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
每日平台使用统计
+
+
+ 时间 +
+ +
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
每日合约操作统计
+
+
+ 时间 +
+ +
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
节点日志详情
+
+
+ 时间范围(单位:日) +
+ +
+ +
+
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
+
合约日志详情
+
+
+ 时间范围(单位:日) +
+ +
+ +
+
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+
+
+
+
账本日志审计
+
+
+
+ +
+
+ 账本: +
+ +
+ Hash: +
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
账本日志详情
+
+
+ 条数范围(单位:条) +
+ +
+ +
+
+
+
+
+
+ Loading... +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
节点配置
+
+
+
+
+ 节点名称 +
+ +
+ +
+
+
+
+
+
+ DOIP配置 +
+ +
+ +
+
+
+
+
+
+ 公网地址 +
+ +
+ +
+
+
+
+
+
+ PeerID +
+ +
+
+
+
+
+ YJS路径 +
+ +
+ +
+
+
+
+
+
+ MasterAddr +
+ +
+ +
+
+
+
+
+
+ 加入网络 +
+ +
+ +
+
+
+
+
+
+ 账本节点 +
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
可信执行集群列表
+
+
+
+ Loading... +
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OnlineIDE.html b/OnlineIDE.html new file mode 100644 index 0000000..fdf4df2 --- /dev/null +++ b/OnlineIDE.html @@ -0,0 +1,733 @@ + + + + + 数瑞智能合约在线编辑器 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ +
+
+ +
+
+
+ +
+
+ + + + +
+ + +
+
+ + +
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+ +
+ + +
+ + + +
+
+ +
+
+ + + + + + +
+
+ +
+
+ + + +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+
+ 查询结果: +
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+ + + + + + + +
+ +
+
+ 执行结果: +
+
+
+
+ +
+
+
+
+ 控制台输出: + +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/OnlineIDE_en.html b/OnlineIDE_en.html new file mode 100644 index 0000000..1209c4c --- /dev/null +++ b/OnlineIDE_en.html @@ -0,0 +1,705 @@ + + + + + BDWare-DOA Online IDE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ +
+
+ +
+ +
+
+ +
+
+ + + + + +
+ + +
+
+ + +
+ +
+
+
+ +
+
+ +
+
+ +
+ +
+ +
+ +
+ + + +
+ + +
+
+ +
+
+ + + +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+
+ Result: +
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+ + + + + + + +
+ +
+
+ Result: +
+
+
+
+ +
+
+
+
+ Console Output: + +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/ProjectTemplate/naiveDAC.zip b/ProjectTemplate/naiveDAC.zip new file mode 100644 index 0000000..8af0b22 Binary files /dev/null and b/ProjectTemplate/naiveDAC.zip differ diff --git a/contractflowchart.html b/contractflowchart.html new file mode 100644 index 0000000..290d86d --- /dev/null +++ b/contractflowchart.html @@ -0,0 +1,87 @@ + +
+ + + 合约分析工具 + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
       合约分析 +
+
+



+
+ +
+
+ +
+
+ + + + + + \ No newline at end of file diff --git a/css/bootstrap-select.css b/css/bootstrap-select.css new file mode 100755 index 0000000..5d4b5b8 --- /dev/null +++ b/css/bootstrap-select.css @@ -0,0 +1,392 @@ +/*! + * Bootstrap-select v1.13.1 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2018 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */ + +select.bs-select-hidden, +.bootstrap-select > select.bs-select-hidden, +select.selectpicker { + display: none !important; +} +.bootstrap-select { + width: 220px \0; + /*IE9 and below*/ +} +.bootstrap-select > .dropdown-toggle { + position: relative; + width: 100%; + z-index: 1; + text-align: right; + white-space: nowrap; +} +.bootstrap-select > .dropdown-toggle.bs-placeholder, +.bootstrap-select > .dropdown-toggle.bs-placeholder:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder:active { + color: #999; +} +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:active { + color: rgba(255, 255, 255, 0.5); +} +.bootstrap-select > select { + position: absolute !important; + bottom: 0; + left: 50%; + display: block !important; + width: 0.5px !important; + height: 100% !important; + padding: 0 !important; + opacity: 0 !important; + border: none; +} +.bootstrap-select > select.mobile-device { + top: 0; + left: 0; + display: block !important; + width: 100% !important; + z-index: 2; +} +.has-error .bootstrap-select .dropdown-toggle, +.error .bootstrap-select .dropdown-toggle, +.bootstrap-select.is-invalid .dropdown-toggle, +.was-validated .bootstrap-select .selectpicker:invalid + .dropdown-toggle { + border-color: #b94a48; +} +.bootstrap-select.is-valid .dropdown-toggle, +.was-validated .bootstrap-select .selectpicker:valid + .dropdown-toggle { + border-color: #28a745; +} +.bootstrap-select.fit-width { + width: auto !important; +} +.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: 220px; +} +.bootstrap-select .dropdown-toggle:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; +} +.bootstrap-select.form-control { + margin-bottom: 0; + padding: 0; + border: none; +} +:not(.input-group) > .bootstrap-select.form-control:not([class*="col-"]) { + width: 100%; +} +.bootstrap-select.form-control.input-group-btn { + z-index: auto; +} +.bootstrap-select.form-control.input-group-btn:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.bootstrap-select:not(.input-group-btn), +.bootstrap-select[class*="col-"] { + float: none; + display: inline-block; + margin-left: 0; +} +.bootstrap-select.dropdown-menu-right, +.bootstrap-select[class*="col-"].dropdown-menu-right, +.row .bootstrap-select[class*="col-"].dropdown-menu-right { + float: right; +} +.form-inline .bootstrap-select, +.form-horizontal .bootstrap-select, +.form-group .bootstrap-select { + margin-bottom: 0; +} +.form-group-lg .bootstrap-select.form-control, +.form-group-sm .bootstrap-select.form-control { + padding: 0; +} +.form-group-lg .bootstrap-select.form-control .dropdown-toggle, +.form-group-sm .bootstrap-select.form-control .dropdown-toggle { + height: 100%; + font-size: inherit; + line-height: inherit; + border-radius: inherit; +} +.bootstrap-select.form-control-sm .dropdown-toggle, +.bootstrap-select.form-control-lg .dropdown-toggle { + font-size: inherit; + line-height: inherit; + border-radius: inherit; +} +.bootstrap-select.form-control-sm .dropdown-toggle { + padding: 0.25rem 0.5rem; +} +.bootstrap-select.form-control-lg .dropdown-toggle { + padding: 0.5rem 1rem; +} +.form-inline .bootstrap-select .form-control { + width: 100%; +} +.bootstrap-select.disabled, +.bootstrap-select > .disabled { + cursor: not-allowed; +} +.bootstrap-select.disabled:focus, +.bootstrap-select > .disabled:focus { + outline: none !important; +} +.bootstrap-select.bs-container { + position: absolute; + top: 0; + left: 0; + height: 0 !important; + padding: 0 !important; +} +.bootstrap-select.bs-container .dropdown-menu { + z-index: 1060; +} +.bootstrap-select .dropdown-toggle:before { + content: ''; + display: inline-block; +} +.bootstrap-select .dropdown-toggle .filter-option { + position: absolute; + top: 0; + left: 0; + padding-top: inherit; + padding-right: inherit; + padding-bottom: inherit; + padding-left: inherit; + height: 100%; + width: 100%; + text-align: left; +} +.bootstrap-select .dropdown-toggle .filter-option-inner { + padding-right: inherit; +} +.bootstrap-select .dropdown-toggle .filter-option-inner-inner { + overflow: hidden; +} +.bootstrap-select .dropdown-toggle .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; +} +.input-group .bootstrap-select.form-control .dropdown-toggle { + border-radius: inherit; +} +.bootstrap-select[class*="col-"] .dropdown-toggle { + width: 100%; +} +.bootstrap-select .dropdown-menu { + min-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bootstrap-select .dropdown-menu > .inner:focus { + outline: none !important; +} +.bootstrap-select .dropdown-menu.inner { + position: static; + float: none; + border: 0; + padding: 0; + margin: 0; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; +} +.bootstrap-select .dropdown-menu li { + position: relative; +} +.bootstrap-select .dropdown-menu li.active small { + color: #fff; +} +.bootstrap-select .dropdown-menu li.disabled a { + cursor: not-allowed; +} +.bootstrap-select .dropdown-menu li a { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.bootstrap-select .dropdown-menu li a.opt { + position: relative; + padding-left: 2.25em; +} +.bootstrap-select .dropdown-menu li a span.check-mark { + display: none; +} +.bootstrap-select .dropdown-menu li a span.text { + display: inline-block; +} +.bootstrap-select .dropdown-menu li small { + padding-left: 0.5em; +} +.bootstrap-select .dropdown-menu .notify { + position: absolute; + bottom: 5px; + width: 96%; + margin: 0 2%; + min-height: 26px; + padding: 3px 5px; + background: #f5f5f5; + border: 1px solid #e3e3e3; + -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); + pointer-events: none; + opacity: 0.9; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bootstrap-select .no-results { + padding: 3px; + background: #f5f5f5; + margin: 0 5px; + white-space: nowrap; +} +.bootstrap-select.fit-width .dropdown-toggle .filter-option { + position: static; + display: inline; + padding: 0; +} +.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner, +.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner { + display: inline; +} +.bootstrap-select.fit-width .dropdown-toggle .caret { + position: static; + top: auto; + margin-top: -1px; +} +.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark { + position: absolute; + display: inline-block; + right: 15px; + top: 5px; +} +.bootstrap-select.show-tick .dropdown-menu li a span.text { + margin-right: 34px; +} +.bootstrap-select .bs-ok-default:after { + content: ''; + display: block; + width: 0.5em; + height: 1em; + border-style: solid; + border-width: 0 0.26em 0.26em 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle { + z-index: 1061; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before { + content: ''; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid rgba(204, 204, 204, 0.2); + position: absolute; + bottom: -4px; + left: 9px; + display: none; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after { + content: ''; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before { + bottom: auto; + top: -4px; + border-top: 7px solid rgba(204, 204, 204, 0.2); + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after { + bottom: auto; + top: -4px; + border-top: 6px solid white; + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before { + right: 12px; + left: auto; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after { + right: 13px; + left: auto; +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:before, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:before, +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:after, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:after { + display: block; +} +.bs-searchbox, +.bs-actionsbox, +.bs-donebutton { + padding: 4px 8px; +} +.bs-actionsbox { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bs-actionsbox .btn-group button { + width: 50%; +} +.bs-donebutton { + float: left; + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bs-donebutton .btn-group button { + width: 100%; +} +.bs-searchbox + .bs-actionsbox { + padding: 0 8px 4px; +} +.bs-searchbox .form-control { + margin-bottom: 0; + width: 100%; + float: none; +} +/*# sourceMappingURL=bootstrap-select.css.map */ \ No newline at end of file diff --git a/css/bootstrap.min.css b/css/bootstrap.min.css new file mode 100755 index 0000000..4a3cde5 --- /dev/null +++ b/css/bootstrap.min.css @@ -0,0 +1 @@ +:root{--blue:#2E324C;--indigo:#6610f2;--purple:#613d7c;--pink:#e83e8c;--red:#FF0039;--orange:#f0ad4e;--yellow:#FF7518;--green:#3FB618;--teal:#20c997;--cyan:#9954BB;--white:#fff;--gray:#868e96;--gray-dark:#373a3c;--primary:#2E324C;--secondary:#868e96;--success:#3FB618;--info:#9954BB;--warning:#FF7518;--danger:#FF0039;--light:#f8f9fa;--dark:#373a3c;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:"Segoe UI","Source Sans Pro",Calibri,Candara,Arial,sans-serif;--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:"Segoe UI","Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-size:.9375rem;font-weight:400;line-height:1.5;color:#373a3c;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#2e324c;text-decoration:none;background-color:transparent}a:hover{color:#11131c;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#868e96;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:300;line-height:1.2}.h1,h1{font-size:2.34375rem}.h2,h2{font-size:1.875rem}.h3,h3{font-size:1.64062rem}.h4,h4{font-size:1.40625rem}.h5,h5{font-size:1.17188rem}.h6,h6{font-size:.9375rem}.lead{font-size:1.17188rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.17188rem}.blockquote-footer{display:block;font-size:80%;color:#868e96}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#868e96}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.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-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.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-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.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-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#373a3c}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#373a3c;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#c4c6cd}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#9294a2}.table-hover .table-primary:hover{background-color:#b6b9c1}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#b6b9c1}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#dddfe2}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#c0c4c8}.table-hover .table-secondary:hover{background-color:#cfd2d6}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#cfd2d6}.table-success,.table-success>td,.table-success>th{background-color:#c9ebbe}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#9bd987}.table-hover .table-success:hover{background-color:#b9e5ab}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b9e5ab}.table-info,.table-info>td,.table-info>th{background-color:#e2cfec}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#caa6dc}.table-hover .table-info:hover{background-color:#d7bde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#d7bde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffd8be}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffb787}.table-hover .table-warning:hover{background-color:#ffc9a5}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffc9a5}.table-danger,.table-danger>td,.table-danger>th{background-color:#ffb8c8}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ff7a98}.table-hover .table-danger:hover{background-color:#ff9fb4}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#ff9fb4}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c7c8c8}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#97999a}.table-hover .table-dark:hover{background-color:#babbbb}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#babbbb}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#373a3c;border-color:#494d50}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#373a3c}.table-dark td,.table-dark th,.table-dark thead th{border-color:#494d50}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:.9375rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#5e669b;outline:0;box-shadow:0 0 0 .2rem rgba(46,50,76,.25)}.form-control::placeholder{color:#868e96;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.17188rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.82031rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#373a3c;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#868e96}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#3fb618}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.82031rem;line-height:1.5;color:#fff;background-color:rgba(63,182,24,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#3fb618;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233FB618' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#3fb618;box-shadow:0 0 0 .2rem rgba(63,182,24,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#3fb618;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23373a3c' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233FB618' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#3fb618;box-shadow:0 0 0 .2rem rgba(63,182,24,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#3fb618}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#3fb618}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#3fb618}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#4fe21f;background-color:#4fe21f}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(63,182,24,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#3fb618}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#3fb618}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#3fb618;box-shadow:0 0 0 .2rem rgba(63,182,24,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#ff0039}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.82031rem;line-height:1.5;color:#fff;background-color:rgba(255,0,57,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#ff0039;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23FF0039' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23FF0039' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .2rem rgba(255,0,57,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#ff0039;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23373a3c' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23FF0039' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23FF0039' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .2rem rgba(255,0,57,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#ff0039}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#ff0039}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#ff0039}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#ff3361;background-color:#ff3361}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(255,0,57,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#ff0039}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#ff0039}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#ff0039;box-shadow:0 0 0 .2rem rgba(255,0,57,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#373a3c;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:.9375rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#373a3c;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(46,50,76,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#2e324c;border-color:#2e324c}.btn-primary:hover{color:#fff;background-color:#202234;border-color:#1b1d2c}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(77,81,103,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#2e324c;border-color:#2e324c}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#1b1d2c;border-color:#161824}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(77,81,103,.5)}.btn-secondary{color:#fff;background-color:#868e96;border-color:#868e96}.btn-secondary:hover{color:#fff;background-color:#727b84;border-color:#6c757d}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(152,159,166,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#868e96;border-color:#868e96}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#666e76}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(152,159,166,.5)}.btn-success{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-success:hover{color:#fff;background-color:#339414;border-color:#2f8912}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(92,193,59,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#2f8912;border-color:#2c7e11}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(92,193,59,.5)}.btn-info{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-info:hover{color:#fff;background-color:#8542a7;border-color:#7e3f9d}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(168,110,197,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#7e3f9d;border-color:#773b94}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(168,110,197,.5)}.btn-warning{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-warning:hover{color:#fff;background-color:#f16100;border-color:#e45c00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,138,59,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#e45c00;border-color:#d75700}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,138,59,.5)}.btn-danger{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-danger:hover{color:#fff;background-color:#d90030;border-color:#cc002e}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(255,38,87,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#cc002e;border-color:#bf002b}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,38,87,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-dark:hover{color:#fff;background-color:#252728;border-color:#1f2021}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(85,88,89,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1f2021;border-color:#191a1b}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(85,88,89,.5)}.btn-outline-primary{color:#2e324c;border-color:#2e324c}.btn-outline-primary:hover{color:#fff;background-color:#2e324c;border-color:#2e324c}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(46,50,76,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#2e324c;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#2e324c;border-color:#2e324c}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(46,50,76,.5)}.btn-outline-secondary{color:#868e96;border-color:#868e96}.btn-outline-secondary:hover{color:#fff;background-color:#868e96;border-color:#868e96}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(134,142,150,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#868e96;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#868e96;border-color:#868e96}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(134,142,150,.5)}.btn-outline-success{color:#3fb618;border-color:#3fb618}.btn-outline-success:hover{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(63,182,24,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#3fb618;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(63,182,24,.5)}.btn-outline-info{color:#9954bb;border-color:#9954bb}.btn-outline-info:hover{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(153,84,187,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#9954bb;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(153,84,187,.5)}.btn-outline-warning{color:#ff7518;border-color:#ff7518}.btn-outline-warning:hover{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,117,24,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ff7518;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,117,24,.5)}.btn-outline-danger{color:#ff0039;border-color:#ff0039}.btn-outline-danger:hover{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(255,0,57,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#ff0039;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,0,57,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#373a3c;border-color:#373a3c}.btn-outline-dark:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(55,58,60,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#373a3c;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(55,58,60,.5)}.btn-link{font-weight:400;color:#2e324c;text-decoration:none}.btn-link:hover{color:#11131c;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#868e96;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:.9375rem;color:#373a3c;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#2e324c}.dropdown-item.disabled,.dropdown-item:disabled{color:#868e96;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.82031rem;color:#868e96;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:.9375rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.17188rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.40625rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#2e324c;background-color:#2e324c}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(46,50,76,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#5e669b}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#7c83b0;border-color:#7c83b0}.custom-control-input:disabled~.custom-control-label{color:#868e96}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.20312rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.20312rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#2e324c;background-color:#2e324c}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(46,50,76,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(46,50,76,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(46,50,76,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.20312rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(46,50,76,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:.9375rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23373a3c' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#5e669b;outline:0;box-shadow:0 0 0 .2rem rgba(46,50,76,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#868e96;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.82031rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.17188rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#5e669b;box-shadow:0 0 0 .2rem rgba(46,50,76,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(46,50,76,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(46,50,76,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(46,50,76,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#2e324c;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#7c83b0}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#2e324c;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#7c83b0}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#2e324c;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#7c83b0}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#868e96;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#868e96;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#2e324c}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.32422rem;padding-bottom:.32422rem;margin-right:1rem;font-size:1.17188rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.17188rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:#fff}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:flex;flex:1 0 0%;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#868e96;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#868e96}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#2e324c;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#11131c;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(46,50,76,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#2e324c;border-color:#2e324c}.page-item.disabled .page-link{color:#868e96;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.17188rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.82031rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#2e324c}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#1b1d2c}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(46,50,76,.5)}.badge-secondary{color:#fff;background-color:#868e96}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#6c757d}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(134,142,150,.5)}.badge-success{color:#fff;background-color:#3fb618}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#2f8912}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(63,182,24,.5)}.badge-info{color:#fff;background-color:#9954bb}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#7e3f9d}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(153,84,187,.5)}.badge-warning{color:#fff;background-color:#ff7518}a.badge-warning:focus,a.badge-warning:hover{color:#fff;background-color:#e45c00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,117,24,.5)}.badge-danger{color:#fff;background-color:#ff0039}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#cc002e}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,0,57,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#373a3c}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1f2021}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(55,58,60,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:0 solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3.90625rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#181a28;background-color:#d5d6db;border-color:#c4c6cd}.alert-primary hr{border-top-color:#b6b9c1}.alert-primary .alert-link{color:#050508}.alert-secondary{color:#464a4e;background-color:#e7e8ea;border-color:#dddfe2}.alert-secondary hr{border-top-color:#cfd2d6}.alert-secondary .alert-link{color:#2e3133}.alert-success{color:#215f0c;background-color:#d9f0d1;border-color:#c9ebbe}.alert-success hr{border-top-color:#b9e5ab}.alert-success .alert-link{color:#113206}.alert-info{color:#502c61;background-color:#ebddf1;border-color:#e2cfec}.alert-info hr{border-top-color:#d7bde5}.alert-info .alert-link{color:#331c3e}.alert-warning{color:#853d0c;background-color:#ffe3d1;border-color:#ffd8be}.alert-warning hr{border-top-color:#ffc9a5}.alert-warning .alert-link{color:#562808}.alert-danger{color:#85001e;background-color:#ffccd7;border-color:#ffb8c8}.alert-danger hr{border-top-color:#ff9fb4}.alert-danger .alert-link{color:#520012}.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:#1d1e1f;background-color:#d7d8d8;border-color:#c7c8c8}.alert-dark hr{border-top-color:#babbbb}.alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{from{background-position:.5rem 0}to{background-position:0 0}}.progress{display:flex;height:.5rem;overflow:hidden;font-size:.70312rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#2e324c;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:.5rem .5rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#373a3c;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#868e96;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#2e324c;border-color:#2e324c}.list-group-horizontal{flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#181a28;background-color:#c4c6cd}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#181a28;background-color:#b6b9c1}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#181a28;border-color:#181a28}.list-group-item-secondary{color:#464a4e;background-color:#dddfe2}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#464a4e;background-color:#cfd2d6}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#464a4e;border-color:#464a4e}.list-group-item-success{color:#215f0c;background-color:#c9ebbe}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#215f0c;background-color:#b9e5ab}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#215f0c;border-color:#215f0c}.list-group-item-info{color:#502c61;background-color:#e2cfec}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#502c61;background-color:#d7bde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#502c61;border-color:#502c61}.list-group-item-warning{color:#853d0c;background-color:#ffd8be}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#853d0c;background-color:#ffc9a5}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#853d0c;border-color:#853d0c}.list-group-item-danger{color:#85001e;background-color:#ffb8c8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#85001e;background-color:#ff9fb4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#85001e;border-color:#85001e}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1d1e1f;background-color:#c7c8c8}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1e1f;background-color:#babbbb}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1e1f;border-color:#1d1e1f}.close{float:right;font-size:1.40625rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#868e96;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;align-items:center;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:"Segoe UI","Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.82031rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:"Segoe UI","Source Sans Pro",Calibri,Candara,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.82031rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:.9375rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#373a3c}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#2e324c!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#1b1d2c!important}.bg-secondary{background-color:#868e96!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#6c757d!important}.bg-success{background-color:#3fb618!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#2f8912!important}.bg-info{background-color:#9954bb!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#7e3f9d!important}.bg-warning{background-color:#ff7518!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#e45c00!important}.bg-danger{background-color:#ff0039!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#cc002e!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#373a3c!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1f2021!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#2e324c!important}.border-secondary{border-color:#868e96!important}.border-success{border-color:#3fb618!important}.border-info{border-color:#9954bb!important}.border-warning{border-color:#ff7518!important}.border-danger{border-color:#ff0039!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#373a3c!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#2e324c!important}a.text-primary:focus,a.text-primary:hover{color:#11131c!important}.text-secondary{color:#868e96!important}a.text-secondary:focus,a.text-secondary:hover{color:#60686f!important}.text-success{color:#3fb618!important}a.text-success:focus,a.text-success:hover{color:#28720f!important}.text-info{color:#9954bb!important}a.text-info:focus,a.text-info:hover{color:#6f378b!important}.text-warning{color:#ff7518!important}a.text-warning:focus,a.text-warning:hover{color:#cb5200!important}.text-danger{color:#ff0039!important}a.text-danger:focus,a.text-danger:hover{color:#b30028!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#373a3c!important}a.text-dark:focus,a.text-dark:hover{color:#121314!important}.text-body{color:#373a3c!important}.text-muted{color:#868e96!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}body{-webkit-font-smoothing:antialiased}.progress .progress-bar{font-size:8px;line-height:8px} \ No newline at end of file diff --git a/css/bootstrap.min.css.old b/css/bootstrap.min.css.old new file mode 100755 index 0000000..c84f8e0 --- /dev/null +++ b/css/bootstrap.min.css.old @@ -0,0 +1,12 @@ +/*! + * Bootswatch v4.4.1 + * Homepage: https://bootswatch.com + * Copyright 2012-2020 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*//*! + * Bootstrap v4.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */@import url("https://fonts.googleapis.com/css?family=Ubuntu:400,700&display=swap");:root{--blue: #007bff;--indigo: #6610f2;--purple: #772953;--pink: #e83e8c;--red: #DF382C;--orange: #E95420;--yellow: #EFB73E;--green: #38B44A;--teal: #20c997;--cyan: #17a2b8;--white: #fff;--gray: #868e96;--gray-dark: #333;--primary: #E95420;--secondary: #AEA79F;--success: #38B44A;--info: #17a2b8;--warning: #EFB73E;--danger: #DF382C;--light: #e9ecef;--dark: #772953;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: "Ubuntu", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}*,*::before,*::after{-webkit-box-sizing:border-box;box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:"Ubuntu", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#333;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0 !important}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:0.5rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-original-title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#E95420;text-decoration:none;background-color:transparent}a:hover{color:#ac3911;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:0.75rem;padding-bottom:0.75rem;color:#868e96;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:0.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button:not(:disabled),[type="button"]:not(:disabled),[type="reset"]:not(:disabled),[type="submit"]:not(:disabled){cursor:pointer}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{padding:0;border-style:none}input[type="radio"],input[type="checkbox"]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:none}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none !important}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{margin-bottom:0.5rem;font-weight:500;line-height:1.2}h1,.h1{font-size:2.5rem}h2,.h2{font-size:2rem}h3,.h3{font-size:1.75rem}h4,.h4{font-size:1.5rem}h5,.h5{font-size:1.25rem}h6,.h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,0.1)}small,.small{font-size:80%;font-weight:400}mark,.mark{padding:0.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:0.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#868e96}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:0.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:0.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:0.5rem;line-height:1}.figure-caption{font-size:90%;color:#868e96}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:0.2rem 0.4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:0.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid,.container-sm,.container-md,.container-lg,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-sm,.container-md{max-width:720px}}@media (min-width: 992px){.container,.container-sm,.container-md,.container-lg{max-width:960px}}@media (min-width: 1200px){.container,.container-sm,.container-md,.container-lg,.container-xl{max-width:1140px}}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*="col-"]{padding-right:0;padding-left:0}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col,.col-auto,.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,.col-sm,.col-sm-auto,.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,.col-md,.col-md-auto,.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,.col-lg,.col-lg-auto,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-webkit-box-flex:0;-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width: 576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-webkit-box-flex:0;-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width: 768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-webkit-box-flex:0;-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width: 992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-webkit-box-flex:0;-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width: 1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-webkit-box-flex:0;-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.3333333333%;flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.6666666667%;flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.3333333333%;flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.6666666667%;flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.3333333333%;flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.6666666667%;flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.3333333333%;flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.6666666667%;flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.table{width:100%;margin-bottom:1rem;color:#333}.table th,.table td{padding:0.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm th,.table-sm td{padding:0.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered th,.table-bordered td{border:1px solid #dee2e6}.table-bordered thead th,.table-bordered thead td{border-bottom-width:2px}.table-borderless th,.table-borderless td,.table-borderless thead th,.table-borderless tbody+tbody{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,0.05)}.table-hover tbody tr:hover{color:#333;background-color:rgba(0,0,0,0.075)}.table-primary,.table-primary>th,.table-primary>td{background-color:#f9cfc1}.table-primary th,.table-primary td,.table-primary thead th,.table-primary tbody+tbody{border-color:#f4a68b}.table-hover .table-primary:hover{background-color:#f7bdaa}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#f7bdaa}.table-secondary,.table-secondary>th,.table-secondary>td{background-color:#e8e6e4}.table-secondary th,.table-secondary td,.table-secondary thead th,.table-secondary tbody+tbody{border-color:#d5d1cd}.table-hover .table-secondary:hover{background-color:#dcd9d6}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#dcd9d6}.table-success,.table-success>th,.table-success>td{background-color:#c7eacc}.table-success th,.table-success td,.table-success thead th,.table-success tbody+tbody{border-color:#98d8a1}.table-hover .table-success:hover{background-color:#b4e3bb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b4e3bb}.table-info,.table-info>th,.table-info>td{background-color:#bee5eb}.table-info th,.table-info td,.table-info thead th,.table-info tbody+tbody{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>th,.table-warning>td{background-color:#fbebc9}.table-warning th,.table-warning td,.table-warning thead th,.table-warning tbody+tbody{border-color:#f7da9b}.table-hover .table-warning:hover{background-color:#f9e2b1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#f9e2b1}.table-danger,.table-danger>th,.table-danger>td{background-color:#f6c7c4}.table-danger th,.table-danger td,.table-danger thead th,.table-danger tbody+tbody{border-color:#ee9891}.table-hover .table-danger:hover{background-color:#f3b2ae}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f3b2ae}.table-light,.table-light>th,.table-light>td{background-color:#f9fafb}.table-light th,.table-light td,.table-light thead th,.table-light tbody+tbody{border-color:#f4f5f7}.table-hover .table-light:hover{background-color:#eaedf1}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#eaedf1}.table-dark,.table-dark>th,.table-dark>td{background-color:#d9c3cf}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#b890a6}.table-hover .table-dark:hover{background-color:#cfb3c3}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#cfb3c3}.table-active,.table-active>th,.table-active>td{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,0.075)}.table .thead-dark th{color:#fff;background-color:#772953;border-color:#642246}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#772953}.table-dark th,.table-dark td,.table-dark thead th{border-color:#642246}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,0.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,0.075)}@media (max-width: 575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width: 767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width: 991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width: 1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:0.375rem 0.75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:0.25rem;-webkit-transition:border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.form-control{-webkit-transition:none;transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#f4ad94;outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25)}.form-control::-webkit-input-placeholder{color:#868e96;opacity:1}.form-control::-ms-input-placeholder{color:#868e96;opacity:1}.form-control::placeholder{color:#868e96;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:0.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#333;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + 0.5rem + 2px);padding:0.25rem 0.5rem;font-size:0.875rem;line-height:1.5;border-radius:0.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:0.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:0.3rem}select.form-control[size],select.form-control[multiple]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:0.25rem}.form-row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*="col-"]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:0.3rem;margin-left:-1.25rem}.form-check-input[disabled] ~ .form-check-label,.form-check-input:disabled ~ .form-check-label{color:#868e96}.form-check-label{margin-bottom:0}.form-check-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:0.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:0.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:0.25rem;font-size:80%;color:#38B44A}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:0.25rem 0.5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(56,180,74,0.9);border-radius:0.25rem}.was-validated :valid ~ .valid-feedback,.was-validated :valid ~ .valid-tooltip,.is-valid ~ .valid-feedback,.is-valid ~ .valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#38B44A;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2338B44A' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#38B44A;-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .custom-select:valid,.custom-select.is-valid{border-color:#38B44A;padding-right:calc(0.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2338B44A' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .custom-select:valid:focus,.custom-select.is-valid:focus{border-color:#38B44A;-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25)}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#38B44A}.was-validated .form-check-input:valid ~ .valid-feedback,.was-validated .form-check-input:valid ~ .valid-tooltip,.form-check-input.is-valid ~ .valid-feedback,.form-check-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-control-input:valid ~ .custom-control-label,.custom-control-input.is-valid ~ .custom-control-label{color:#38B44A}.was-validated .custom-control-input:valid ~ .custom-control-label::before,.custom-control-input.is-valid ~ .custom-control-label::before{border-color:#38B44A}.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before,.custom-control-input.is-valid:checked ~ .custom-control-label::before{border-color:#55ca66;background-color:#55ca66}.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before,.custom-control-input.is-valid:focus ~ .custom-control-label::before{-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25)}.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before,.custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before{border-color:#38B44A}.was-validated .custom-file-input:valid ~ .custom-file-label,.custom-file-input.is-valid ~ .custom-file-label{border-color:#38B44A}.was-validated .custom-file-input:valid:focus ~ .custom-file-label,.custom-file-input.is-valid:focus ~ .custom-file-label{border-color:#38B44A;-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.25)}.invalid-feedback{display:none;width:100%;margin-top:0.25rem;font-size:80%;color:#DF382C}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:0.25rem 0.5rem;margin-top:.1rem;font-size:0.875rem;line-height:1.5;color:#fff;background-color:rgba(223,56,44,0.9);border-radius:0.25rem}.was-validated :invalid ~ .invalid-feedback,.was-validated :invalid ~ .invalid-tooltip,.is-invalid ~ .invalid-feedback,.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#DF382C;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23DF382C' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23DF382C' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#DF382C;-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .custom-select:invalid,.custom-select.is-invalid{border-color:#DF382C;padding-right:calc(0.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23DF382C' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23DF382C' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .custom-select:invalid:focus,.custom-select.is-invalid:focus{border-color:#DF382C;-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25)}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#DF382C}.was-validated .form-check-input:invalid ~ .invalid-feedback,.was-validated .form-check-input:invalid ~ .invalid-tooltip,.form-check-input.is-invalid ~ .invalid-feedback,.form-check-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-control-input:invalid ~ .custom-control-label,.custom-control-input.is-invalid ~ .custom-control-label{color:#DF382C}.was-validated .custom-control-input:invalid ~ .custom-control-label::before,.custom-control-input.is-invalid ~ .custom-control-label::before{border-color:#DF382C}.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before,.custom-control-input.is-invalid:checked ~ .custom-control-label::before{border-color:#e66258;background-color:#e66258}.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before,.custom-control-input.is-invalid:focus ~ .custom-control-label::before{-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25)}.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before,.custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before{border-color:#DF382C}.was-validated .custom-file-input:invalid ~ .custom-file-label,.custom-file-input.is-invalid ~ .custom-file-label{border-color:#DF382C}.was-validated .custom-file-input:invalid:focus ~ .custom-file-label,.custom-file-input.is-invalid:focus ~ .custom-file-label{border-color:#DF382C;-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.25)}.form-inline{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select{width:auto}.form-inline .form-check{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:0.25rem;margin-left:0}.form-inline .custom-control{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#333;text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:0.375rem 0.75rem;font-size:1rem;line-height:1.5;border-radius:0.25rem;-webkit-transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.btn{-webkit-transition:none;transition:none}}.btn:hover{color:#333;text-decoration:none}.btn:focus,.btn.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25)}.btn.disabled,.btn:disabled{opacity:0.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#E95420;border-color:#E95420}.btn-primary:hover{color:#fff;background-color:#ce4414;border-color:#c34113}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#ce4414;border-color:#c34113;-webkit-box-shadow:0 0 0 0.2rem rgba(236,110,65,0.5);box-shadow:0 0 0 0.2rem rgba(236,110,65,0.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#E95420;border-color:#E95420}.btn-primary:not(:disabled):not(.disabled):active,.btn-primary:not(:disabled):not(.disabled).active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#c34113;border-color:#b73d12}.btn-primary:not(:disabled):not(.disabled):active:focus,.btn-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-primary.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(236,110,65,0.5);box-shadow:0 0 0 0.2rem rgba(236,110,65,0.5)}.btn-secondary{color:#fff;background-color:#AEA79F;border-color:#AEA79F}.btn-secondary:hover{color:#fff;background-color:#9c948a;border-color:#978e83}.btn-secondary:focus,.btn-secondary.focus{color:#fff;background-color:#9c948a;border-color:#978e83;-webkit-box-shadow:0 0 0 0.2rem rgba(186,180,173,0.5);box-shadow:0 0 0 0.2rem rgba(186,180,173,0.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#AEA79F;border-color:#AEA79F}.btn-secondary:not(:disabled):not(.disabled):active,.btn-secondary:not(:disabled):not(.disabled).active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#978e83;border-color:#91877c}.btn-secondary:not(:disabled):not(.disabled):active:focus,.btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(186,180,173,0.5);box-shadow:0 0 0 0.2rem rgba(186,180,173,0.5)}.btn-success{color:#fff;background-color:#38B44A;border-color:#38B44A}.btn-success:hover{color:#fff;background-color:#2f973e;border-color:#2c8d3a}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#2f973e;border-color:#2c8d3a;-webkit-box-shadow:0 0 0 0.2rem rgba(86,191,101,0.5);box-shadow:0 0 0 0.2rem rgba(86,191,101,0.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#38B44A;border-color:#38B44A}.btn-success:not(:disabled):not(.disabled):active,.btn-success:not(:disabled):not(.disabled).active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#2c8d3a;border-color:#298336}.btn-success:not(:disabled):not(.disabled):active:focus,.btn-success:not(:disabled):not(.disabled).active:focus,.show>.btn-success.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(86,191,101,0.5);box-shadow:0 0 0 0.2rem rgba(86,191,101,0.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#138496;border-color:#117a8b;-webkit-box-shadow:0 0 0 0.2rem rgba(58,176,195,0.5);box-shadow:0 0 0 0.2rem rgba(58,176,195,0.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled):active,.btn-info:not(:disabled):not(.disabled).active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled):active:focus,.btn-info:not(:disabled):not(.disabled).active:focus,.show>.btn-info.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(58,176,195,0.5);box-shadow:0 0 0 0.2rem rgba(58,176,195,0.5)}.btn-warning{color:#fff;background-color:#EFB73E;border-color:#EFB73E}.btn-warning:hover{color:#fff;background-color:#ecaa1b;border-color:#e7a413}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ecaa1b;border-color:#e7a413;-webkit-box-shadow:0 0 0 0.2rem rgba(241,194,91,0.5);box-shadow:0 0 0 0.2rem rgba(241,194,91,0.5)}.btn-warning.disabled,.btn-warning:disabled{color:#fff;background-color:#EFB73E;border-color:#EFB73E}.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled).active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#e7a413;border-color:#db9c12}.btn-warning:not(:disabled):not(.disabled):active:focus,.btn-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-warning.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(241,194,91,0.5);box-shadow:0 0 0 0.2rem rgba(241,194,91,0.5)}.btn-danger{color:#fff;background-color:#DF382C;border-color:#DF382C}.btn-danger:hover{color:#fff;background-color:#c7291e;border-color:#bc271c}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c7291e;border-color:#bc271c;-webkit-box-shadow:0 0 0 0.2rem rgba(228,86,76,0.5);box-shadow:0 0 0 0.2rem rgba(228,86,76,0.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#DF382C;border-color:#DF382C}.btn-danger:not(:disabled):not(.disabled):active,.btn-danger:not(:disabled):not(.disabled).active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bc271c;border-color:#b0251b}.btn-danger:not(:disabled):not(.disabled):active:focus,.btn-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-danger.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(228,86,76,0.5);box-shadow:0 0 0 0.2rem rgba(228,86,76,0.5)}.btn-light{color:#212529;background-color:#e9ecef;border-color:#e9ecef}.btn-light:hover{color:#212529;background-color:#d3d9df;border-color:#cbd3da}.btn-light:focus,.btn-light.focus{color:#212529;background-color:#d3d9df;border-color:#cbd3da;-webkit-box-shadow:0 0 0 0.2rem rgba(203,206,209,0.5);box-shadow:0 0 0 0.2rem rgba(203,206,209,0.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#e9ecef;border-color:#e9ecef}.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled).active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#cbd3da;border-color:#c4ccd4}.btn-light:not(:disabled):not(.disabled):active:focus,.btn-light:not(:disabled):not(.disabled).active:focus,.show>.btn-light.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(203,206,209,0.5);box-shadow:0 0 0 0.2rem rgba(203,206,209,0.5)}.btn-dark{color:#fff;background-color:#772953;border-color:#772953}.btn-dark:hover{color:#fff;background-color:#5b1f3f;border-color:#511c39}.btn-dark:focus,.btn-dark.focus{color:#fff;background-color:#5b1f3f;border-color:#511c39;-webkit-box-shadow:0 0 0 0.2rem rgba(139,73,109,0.5);box-shadow:0 0 0 0.2rem rgba(139,73,109,0.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#772953;border-color:#772953}.btn-dark:not(:disabled):not(.disabled):active,.btn-dark:not(:disabled):not(.disabled).active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#511c39;border-color:#481932}.btn-dark:not(:disabled):not(.disabled):active:focus,.btn-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-dark.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(139,73,109,0.5);box-shadow:0 0 0 0.2rem rgba(139,73,109,0.5)}.btn-outline-primary{color:#E95420;border-color:#E95420}.btn-outline-primary:hover{color:#fff;background-color:#E95420;border-color:#E95420}.btn-outline-primary:focus,.btn-outline-primary.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.5);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#E95420;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled):active,.btn-outline-primary:not(:disabled):not(.disabled).active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#E95420;border-color:#E95420}.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.5);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.5)}.btn-outline-secondary{color:#AEA79F;border-color:#AEA79F}.btn-outline-secondary:hover{color:#fff;background-color:#AEA79F;border-color:#AEA79F}.btn-outline-secondary:focus,.btn-outline-secondary.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(174,167,159,0.5);box-shadow:0 0 0 0.2rem rgba(174,167,159,0.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#AEA79F;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled):active,.btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#AEA79F;border-color:#AEA79F}.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(174,167,159,0.5);box-shadow:0 0 0 0.2rem rgba(174,167,159,0.5)}.btn-outline-success{color:#38B44A;border-color:#38B44A}.btn-outline-success:hover{color:#fff;background-color:#38B44A;border-color:#38B44A}.btn-outline-success:focus,.btn-outline-success.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.5);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#38B44A;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled):active,.btn-outline-success:not(:disabled):not(.disabled).active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#38B44A;border-color:#38B44A}.btn-outline-success:not(:disabled):not(.disabled):active:focus,.btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-success.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.5);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:focus,.btn-outline-info.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(23,162,184,0.5);box-shadow:0 0 0 0.2rem rgba(23,162,184,0.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled):active,.btn-outline-info:not(:disabled):not(.disabled).active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled):active:focus,.btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-info.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(23,162,184,0.5);box-shadow:0 0 0 0.2rem rgba(23,162,184,0.5)}.btn-outline-warning{color:#EFB73E;border-color:#EFB73E}.btn-outline-warning:hover{color:#fff;background-color:#EFB73E;border-color:#EFB73E}.btn-outline-warning:focus,.btn-outline-warning.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(239,183,62,0.5);box-shadow:0 0 0 0.2rem rgba(239,183,62,0.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#EFB73E;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled):active,.btn-outline-warning:not(:disabled):not(.disabled).active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#EFB73E;border-color:#EFB73E}.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(239,183,62,0.5);box-shadow:0 0 0 0.2rem rgba(239,183,62,0.5)}.btn-outline-danger{color:#DF382C;border-color:#DF382C}.btn-outline-danger:hover{color:#fff;background-color:#DF382C;border-color:#DF382C}.btn-outline-danger:focus,.btn-outline-danger.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.5);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#DF382C;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled):active,.btn-outline-danger:not(:disabled):not(.disabled).active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#DF382C;border-color:#DF382C}.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.5);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.5)}.btn-outline-light{color:#e9ecef;border-color:#e9ecef}.btn-outline-light:hover{color:#212529;background-color:#e9ecef;border-color:#e9ecef}.btn-outline-light:focus,.btn-outline-light.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(233,236,239,0.5);box-shadow:0 0 0 0.2rem rgba(233,236,239,0.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#e9ecef;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled):active,.btn-outline-light:not(:disabled):not(.disabled).active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#e9ecef;border-color:#e9ecef}.btn-outline-light:not(:disabled):not(.disabled):active:focus,.btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-light.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(233,236,239,0.5);box-shadow:0 0 0 0.2rem rgba(233,236,239,0.5)}.btn-outline-dark{color:#772953;border-color:#772953}.btn-outline-dark:hover{color:#fff;background-color:#772953;border-color:#772953}.btn-outline-dark:focus,.btn-outline-dark.focus{-webkit-box-shadow:0 0 0 0.2rem rgba(119,41,83,0.5);box-shadow:0 0 0 0.2rem rgba(119,41,83,0.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#772953;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled):active,.btn-outline-dark:not(:disabled):not(.disabled).active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#772953;border-color:#772953}.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{-webkit-box-shadow:0 0 0 0.2rem rgba(119,41,83,0.5);box-shadow:0 0 0 0.2rem rgba(119,41,83,0.5)}.btn-link{font-weight:400;color:#E95420;text-decoration:none}.btn-link:hover{color:#ac3911;text-decoration:underline}.btn-link:focus,.btn-link.focus{text-decoration:underline;-webkit-box-shadow:none;box-shadow:none}.btn-link:disabled,.btn-link.disabled{color:#868e96;pointer-events:none}.btn-lg,.btn-group-lg>.btn{padding:0.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:0.3rem}.btn-sm,.btn-group-sm>.btn{padding:0.25rem 0.5rem;font-size:0.875rem;line-height:1.5;border-radius:0.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:0.5rem}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{-webkit-transition:opacity 0.15s linear;transition:opacity 0.15s linear}@media (prefers-reduced-motion: reduce){.fade{-webkit-transition:none;transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;transition:height 0.35s ease}@media (prefers-reduced-motion: reduce){.collapsing{-webkit-transition:none;transition:none}}.dropup,.dropright,.dropdown,.dropleft{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:0.255em;vertical-align:0.255em;content:"";border-top:0.3em solid;border-right:0.3em solid transparent;border-bottom:0;border-left:0.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:0.5rem 0;margin:0.125rem 0 0;font-size:1rem;color:#333;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.15);border-radius:0.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width: 576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width: 768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width: 992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width: 1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:0.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:0.255em;vertical-align:0.255em;content:"";border-top:0;border-right:0.3em solid transparent;border-bottom:0.3em solid;border-left:0.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:0.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:0.255em;vertical-align:0.255em;content:"";border-top:0.3em solid transparent;border-right:0;border-bottom:0.3em solid transparent;border-left:0.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:0.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:0.255em;vertical-align:0.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:0.255em;vertical-align:0.255em;content:"";border-top:0.3em solid transparent;border-right:0.3em solid;border-bottom:0.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^="top"],.dropdown-menu[x-placement^="right"],.dropdown-menu[x-placement^="bottom"],.dropdown-menu[x-placement^="left"]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:0.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:0.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#E95420}.dropdown-item.disabled,.dropdown-item:disabled{color:#868e96;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:0.5rem 1.5rem;margin-bottom:0;font-size:0.875rem;color:#868e96;white-space:nowrap}.dropdown-item-text{display:block;padding:0.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover{z-index:1}.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:0.5625rem;padding-left:0.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:0.375rem;padding-left:0.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:0.75rem;padding-left:0.75rem}.btn-group-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type="radio"],.btn-group-toggle>.btn input[type="checkbox"],.btn-group-toggle>.btn-group>.btn input[type="radio"],.btn-group-toggle>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-control-plaintext,.input-group>.custom-select,.input-group>.custom-file{position:relative;-webkit-box-flex:1;-ms-flex:1 1 0%;flex:1 1 0%;min-width:0;margin-bottom:0}.input-group>.form-control+.form-control,.input-group>.form-control+.custom-select,.input-group>.form-control+.custom-file,.input-group>.form-control-plaintext+.form-control,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.custom-file,.input-group>.custom-select+.form-control,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.custom-file,.input-group>.custom-file+.form-control,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.custom-file{margin-left:-1px}.input-group>.form-control:focus,.input-group>.custom-select:focus,.input-group>.custom-file .custom-file-input:focus ~ .custom-file-label{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.form-control:not(:last-child),.input-group>.custom-select:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-control:not(:first-child),.input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-prepend,.input-group-append{display:-webkit-box;display:-ms-flexbox;display:flex}.input-group-prepend .btn,.input-group-append .btn{position:relative;z-index:2}.input-group-prepend .btn:focus,.input-group-append .btn:focus{z-index:3}.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.input-group-text,.input-group-append .input-group-text+.btn{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0.375rem 0.75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:0.25rem}.input-group-text input[type="radio"],.input-group-text input[type="checkbox"]{margin-top:0}.input-group-lg>.form-control:not(textarea),.input-group-lg>.custom-select{height:calc(1.5em + 1rem + 2px)}.input-group-lg>.form-control,.input-group-lg>.custom-select,.input-group-lg>.input-group-prepend>.input-group-text,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-append>.btn{padding:0.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:0.3rem}.input-group-sm>.form-control:not(textarea),.input-group-sm>.custom-select{height:calc(1.5em + 0.5rem + 2px)}.input-group-sm>.form-control,.input-group-sm>.custom-select,.input-group-sm>.input-group-prepend>.input-group-text,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-append>.btn{padding:0.25rem 0.5rem;font-size:0.875rem;line-height:1.5;border-radius:0.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text,.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked ~ .custom-control-label::before{color:#fff;border-color:#E95420;background-color:#E95420}.custom-control-input:focus ~ .custom-control-label::before{-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25)}.custom-control-input:focus:not(:checked) ~ .custom-control-label::before{border-color:#f4ad94}.custom-control-input:not(:disabled):active ~ .custom-control-label::before{color:#fff;background-color:#f9d1c2;border-color:#f9d1c2}.custom-control-input[disabled] ~ .custom-control-label,.custom-control-input:disabled ~ .custom-control-label{color:#868e96}.custom-control-input[disabled] ~ .custom-control-label::before,.custom-control-input:disabled ~ .custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:0.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#AEA79F solid 1px}.custom-control-label::after{position:absolute;top:0.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50% / 50% 50%}.custom-checkbox .custom-control-label::before{border-radius:0.25rem}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before{border-color:#E95420;background-color:#E95420}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(233,84,32,0.5)}.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before{background-color:rgba(233,84,32,0.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(233,84,32,0.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:0.5rem}.custom-switch .custom-control-label::after{top:calc(0.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#AEA79F;border-radius:0.5rem;-webkit-transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-transform 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.custom-switch .custom-control-label::after{-webkit-transition:none;transition:none}}.custom-switch .custom-control-input:checked ~ .custom-control-label::after{background-color:#fff;-webkit-transform:translateX(0.75rem);transform:translateX(0.75rem)}.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(233,84,32,0.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);padding:0.375rem 1.75rem 0.375rem 0.75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px;border:1px solid #ced4da;border-radius:0.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#f4ad94;outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:0.75rem;background-image:none}.custom-select:disabled{color:#868e96;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + 0.5rem + 2px);padding-top:0.25rem;padding-bottom:0.25rem;padding-left:0.5rem;font-size:0.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:0.5rem;padding-bottom:0.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + 0.75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + 0.75rem + 2px);margin:0;opacity:0}.custom-file-input:focus ~ .custom-file-label{border-color:#f4ad94;-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25)}.custom-file-input[disabled] ~ .custom-file-label,.custom-file-input:disabled ~ .custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en) ~ .custom-file-label::after{content:"Browse"}.custom-file-input ~ .custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + 0.75rem + 2px);padding:0.375rem 0.75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:0.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + 0.75rem);padding:0.375rem 0.75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 0.25rem 0.25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:none}.custom-range:focus::-webkit-slider-thumb{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 1px #fff,0 0 0 0.2rem rgba(233,84,32,0.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0.2rem rgba(233,84,32,0.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 0.2rem rgba(233,84,32,0.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#E95420;border:0;border-radius:1rem;-webkit-transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#f9d1c2}.custom-range::-webkit-slider-runnable-track{width:100%;height:0.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#E95420;border:0;border-radius:1rem;-webkit-transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-moz-range-thumb{-webkit-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#f9d1c2}.custom-range::-moz-range-track{width:100%;height:0.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:0.2rem;margin-left:0.2rem;background-color:#E95420;border:0;border-radius:1rem;-webkit-transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;appearance:none}@media (prefers-reduced-motion: reduce){.custom-range::-ms-thumb{-webkit-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#f9d1c2}.custom-range::-ms-track{width:100%;height:0.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:0.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#AEA79F}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#AEA79F}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#AEA79F}.custom-control-label::before,.custom-file-label,.custom-select{-webkit-transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.custom-control-label::before,.custom-file-label,.custom-select{-webkit-transition:none;transition:none}}.nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:0.5rem 1rem}.nav-link:hover,.nav-link:focus{text-decoration:none}.nav-link.disabled{color:#868e96;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:0.25rem;border-top-right-radius:0.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#868e96;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:0.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#E95420}.nav-fill .nav-item{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-sm,.navbar .container-md,.navbar .container-lg,.navbar .container-xl{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:0.3125rem;padding-bottom:0.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:0.5rem;padding-bottom:0.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:0.25rem 0.75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:0.25rem}.navbar-toggler:hover,.navbar-toggler:focus{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width: 575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 576px){.navbar-expand-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:0.5rem;padding-left:0.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width: 767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 768px){.navbar-expand-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:0.5rem;padding-left:0.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-md,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width: 991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 992px){.navbar-expand-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:0.5rem;padding-left:0.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width: 1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width: 1200px){.navbar-expand-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:0.5rem;padding-left:0.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:0.5rem;padding-left:0.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-sm,.navbar-expand>.container-md,.navbar-expand>.container-lg,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,0.9)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:rgba(0,0,0,0.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,0.5)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(0,0,0,0.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,0.3)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .nav-link.active{color:rgba(0,0,0,0.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,0.5);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,0.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,0.9)}.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:rgba(0,0,0,0.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,0.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,0.25)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,0.5);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,0.125);border-radius:0.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:0.25rem;border-top-right-radius:0.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:0.25rem;border-bottom-left-radius:0.25rem}.card-body{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:0.75rem}.card-subtitle{margin-top:-0.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:0.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,0.03);border-bottom:1px solid rgba(0,0,0,0.125)}.card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:0.75rem 1.25rem;background-color:rgba(0,0,0,0.03);border-top:1px solid rgba(0,0,0,0.125)}.card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.card-header-tabs{margin-right:-0.625rem;margin-bottom:-0.75rem;margin-left:-0.625rem;border-bottom:0}.card-header-pills{margin-right:-0.625rem;margin-left:-0.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-top,.card-img-bottom{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width: 576px){.card-deck{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width: 576px){.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:0.75rem}@media (min-width: 576px){.card-columns{-webkit-column-count:3;column-count:3;-webkit-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:0.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:0.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:0.5rem;color:#868e96;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#868e96}.pagination{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:0.25rem}.page-link{position:relative;display:block;padding:0.5rem 0.75rem;margin-left:-1px;line-height:1.25;color:#E95420;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#ac3911;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:0.25rem;border-bottom-left-radius:0.25rem}.page-item:last-child .page-link{border-top-right-radius:0.25rem;border-bottom-right-radius:0.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#E95420;border-color:#E95420}.page-item.disabled .page-link{color:#868e96;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:0.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:0.3rem;border-bottom-left-radius:0.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:0.3rem;border-bottom-right-radius:0.3rem}.pagination-sm .page-link{padding:0.25rem 0.5rem;font-size:0.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:0.2rem;border-bottom-left-radius:0.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:0.2rem;border-bottom-right-radius:0.2rem}.badge{display:inline-block;padding:0.25em 0.4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:0.25rem;-webkit-transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;transition:color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out}@media (prefers-reduced-motion: reduce){.badge{-webkit-transition:none;transition:none}}a.badge:hover,a.badge:focus{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:0.6em;padding-left:0.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#E95420}a.badge-primary:hover,a.badge-primary:focus{color:#fff;background-color:#c34113}a.badge-primary:focus,a.badge-primary.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(233,84,32,0.5);box-shadow:0 0 0 0.2rem rgba(233,84,32,0.5)}.badge-secondary{color:#fff;background-color:#AEA79F}a.badge-secondary:hover,a.badge-secondary:focus{color:#fff;background-color:#978e83}a.badge-secondary:focus,a.badge-secondary.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(174,167,159,0.5);box-shadow:0 0 0 0.2rem rgba(174,167,159,0.5)}.badge-success{color:#fff;background-color:#38B44A}a.badge-success:hover,a.badge-success:focus{color:#fff;background-color:#2c8d3a}a.badge-success:focus,a.badge-success.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(56,180,74,0.5);box-shadow:0 0 0 0.2rem rgba(56,180,74,0.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:hover,a.badge-info:focus{color:#fff;background-color:#117a8b}a.badge-info:focus,a.badge-info.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(23,162,184,0.5);box-shadow:0 0 0 0.2rem rgba(23,162,184,0.5)}.badge-warning{color:#fff;background-color:#EFB73E}a.badge-warning:hover,a.badge-warning:focus{color:#fff;background-color:#e7a413}a.badge-warning:focus,a.badge-warning.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(239,183,62,0.5);box-shadow:0 0 0 0.2rem rgba(239,183,62,0.5)}.badge-danger{color:#fff;background-color:#DF382C}a.badge-danger:hover,a.badge-danger:focus{color:#fff;background-color:#bc271c}a.badge-danger:focus,a.badge-danger.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(223,56,44,0.5);box-shadow:0 0 0 0.2rem rgba(223,56,44,0.5)}.badge-light{color:#212529;background-color:#e9ecef}a.badge-light:hover,a.badge-light:focus{color:#212529;background-color:#cbd3da}a.badge-light:focus,a.badge-light.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(233,236,239,0.5);box-shadow:0 0 0 0.2rem rgba(233,236,239,0.5)}.badge-dark{color:#fff;background-color:#772953}a.badge-dark:hover,a.badge-dark:focus{color:#fff;background-color:#511c39}a.badge-dark:focus,a.badge-dark.focus{outline:0;-webkit-box-shadow:0 0 0 0.2rem rgba(119,41,83,0.5);box-shadow:0 0 0 0.2rem rgba(119,41,83,0.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:0.3rem}@media (min-width: 576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.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:#792c11;background-color:#fbddd2;border-color:#f9cfc1}.alert-primary hr{border-top-color:#f7bdaa}.alert-primary .alert-link{color:#4c1c0b}.alert-secondary{color:#5a5753;background-color:#efedec;border-color:#e8e6e4}.alert-secondary hr{border-top-color:#dcd9d6}.alert-secondary .alert-link{color:#3f3d3b}.alert-success{color:#1d5e26;background-color:#d7f0db;border-color:#c7eacc}.alert-success hr{border-top-color:#b4e3bb}.alert-success .alert-link{color:#113716}.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:#7c5f20;background-color:#fcf1d8;border-color:#fbebc9}.alert-warning hr{border-top-color:#f9e2b1}.alert-warning .alert-link{color:#534016}.alert-danger{color:#741d17;background-color:#f9d7d5;border-color:#f6c7c4}.alert-danger hr{border-top-color:#f3b2ae}.alert-danger .alert-link{color:#49120f}.alert-light{color:#797b7c;background-color:#fbfbfc;border-color:#f9fafb}.alert-light hr{border-top-color:#eaedf1}.alert-light .alert-link{color:#606162}.alert-dark{color:#3e152b;background-color:#e4d4dd;border-color:#d9c3cf}.alert-dark hr{border-top-color:#cfb3c3}.alert-dark .alert-link{color:#180811}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-webkit-box;display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:0.75rem;background-color:#e9ecef;border-radius:0.25rem}.progress-bar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#E95420;-webkit-transition:width 0.6s ease;transition:width 0.6s ease}@media (prefers-reduced-motion: reduce){.progress-bar{-webkit-transition:none;transition:none}}.progress-bar-striped{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:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion: reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.media-body{-webkit-box-flex:1;-ms-flex:1;flex:1}.list-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#333;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:0.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,0.125)}.list-group-item:first-child{border-top-left-radius:0.25rem;border-top-right-radius:0.25rem}.list-group-item:last-child{border-bottom-right-radius:0.25rem;border-bottom-left-radius:0.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#868e96;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#E95420;border-color:#E95420}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item:first-child{border-bottom-left-radius:0.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{border-top-right-radius:0.25rem;border-bottom-left-radius:0}.list-group-horizontal .list-group-item.active{margin-top:0}.list-group-horizontal .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width: 576px){.list-group-horizontal-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item:first-child{border-bottom-left-radius:0.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{border-top-right-radius:0.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm .list-group-item.active{margin-top:0}.list-group-horizontal-sm .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 768px){.list-group-horizontal-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item:first-child{border-bottom-left-radius:0.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{border-top-right-radius:0.25rem;border-bottom-left-radius:0}.list-group-horizontal-md .list-group-item.active{margin-top:0}.list-group-horizontal-md .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 992px){.list-group-horizontal-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item:first-child{border-bottom-left-radius:0.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{border-top-right-radius:0.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg .list-group-item.active{margin-top:0}.list-group-horizontal-lg .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width: 1200px){.list-group-horizontal-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item:first-child{border-bottom-left-radius:0.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{border-top-right-radius:0.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl .list-group-item.active{margin-top:0}.list-group-horizontal-xl .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush .list-group-item{border-right-width:0;border-left-width:0;border-radius:0}.list-group-flush .list-group-item:first-child{border-top-width:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#792c11;background-color:#f9cfc1}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#792c11;background-color:#f7bdaa}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#792c11;border-color:#792c11}.list-group-item-secondary{color:#5a5753;background-color:#e8e6e4}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#5a5753;background-color:#dcd9d6}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#5a5753;border-color:#5a5753}.list-group-item-success{color:#1d5e26;background-color:#c7eacc}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#1d5e26;background-color:#b4e3bb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#1d5e26;border-color:#1d5e26}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#7c5f20;background-color:#fbebc9}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#7c5f20;background-color:#f9e2b1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#7c5f20;border-color:#7c5f20}.list-group-item-danger{color:#741d17;background-color:#f6c7c4}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#741d17;background-color:#f3b2ae}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#741d17;border-color:#741d17}.list-group-item-light{color:#797b7c;background-color:#f9fafb}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#797b7c;background-color:#eaedf1}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#797b7c;border-color:#797b7c}.list-group-item-dark{color:#3e152b;background-color:#d9c3cf}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#3e152b;background-color:#cfb3c3}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#3e152b;border-color:#3e152b}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):hover,.close:not(:disabled):not(.disabled):focus{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:0.875rem;background-color:rgba(255,255,255,0.85);background-clip:padding-box;border:1px solid rgba(0,0,0,0.1);-webkit-box-shadow:0 0.25rem 0.75rem rgba(0,0,0,0.1);box-shadow:0 0.25rem 0.75rem rgba(0,0,0,0.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:0.25rem}.toast:not(:last-child){margin-bottom:0.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0.25rem 0.75rem;color:#868e96;background-color:rgba(255,255,255,0.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,0.05)}.toast-body{padding:0.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:0.5rem;pointer-events:none}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform 0.3s ease-out;transition:-webkit-transform 0.3s ease-out;transition:transform 0.3s ease-out;transition:transform 0.3s ease-out, -webkit-transform 0.3s ease-out;-webkit-transform:translate(0, -50px);transform:translate(0, -50px)}@media (prefers-reduced-motion: reduce){.modal.fade .modal-dialog{-webkit-transition:none;transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-webkit-box;display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-header,.modal-dialog-scrollable .modal-footer{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:0.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:0.5}.modal-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:0.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(0.3rem - 1px);border-bottom-left-radius:calc(0.3rem - 1px)}.modal-footer>*{margin:0.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width: 1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:"Ubuntu", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:0.9}.tooltip .arrow{position:absolute;display:block;width:0.8rem;height:0.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[x-placement^="top"]{padding:0.4rem 0}.bs-tooltip-top .arrow,.bs-tooltip-auto[x-placement^="top"] .arrow{bottom:0}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[x-placement^="top"] .arrow::before{top:0;border-width:0.4rem 0.4rem 0;border-top-color:#000}.bs-tooltip-right,.bs-tooltip-auto[x-placement^="right"]{padding:0 0.4rem}.bs-tooltip-right .arrow,.bs-tooltip-auto[x-placement^="right"] .arrow{left:0;width:0.4rem;height:0.8rem}.bs-tooltip-right .arrow::before,.bs-tooltip-auto[x-placement^="right"] .arrow::before{right:0;border-width:0.4rem 0.4rem 0.4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[x-placement^="bottom"]{padding:0.4rem 0}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[x-placement^="bottom"] .arrow{top:0}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[x-placement^="bottom"] .arrow::before{bottom:0;border-width:0 0.4rem 0.4rem;border-bottom-color:#000}.bs-tooltip-left,.bs-tooltip-auto[x-placement^="left"]{padding:0 0.4rem}.bs-tooltip-left .arrow,.bs-tooltip-auto[x-placement^="left"] .arrow{right:0;width:0.4rem;height:0.8rem}.bs-tooltip-left .arrow::before,.bs-tooltip-auto[x-placement^="left"] .arrow::before{left:0;border-width:0.4rem 0 0.4rem 0.4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:0.25rem 0.5rem;color:#fff;text-align:center;background-color:#000;border-radius:0.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:"Ubuntu", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:0.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:0.5rem;margin:0 0.3rem}.popover .arrow::before,.popover .arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top,.bs-popover-auto[x-placement^="top"]{margin-bottom:0.5rem}.bs-popover-top>.arrow,.bs-popover-auto[x-placement^="top"]>.arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.arrow::before,.bs-popover-auto[x-placement^="top"]>.arrow::before{bottom:0;border-width:0.5rem 0.5rem 0;border-top-color:rgba(0,0,0,0.25)}.bs-popover-top>.arrow::after,.bs-popover-auto[x-placement^="top"]>.arrow::after{bottom:1px;border-width:0.5rem 0.5rem 0;border-top-color:#fff}.bs-popover-right,.bs-popover-auto[x-placement^="right"]{margin-left:0.5rem}.bs-popover-right>.arrow,.bs-popover-auto[x-placement^="right"]>.arrow{left:calc(-0.5rem - 1px);width:0.5rem;height:1rem;margin:0.3rem 0}.bs-popover-right>.arrow::before,.bs-popover-auto[x-placement^="right"]>.arrow::before{left:0;border-width:0.5rem 0.5rem 0.5rem 0;border-right-color:rgba(0,0,0,0.25)}.bs-popover-right>.arrow::after,.bs-popover-auto[x-placement^="right"]>.arrow::after{left:1px;border-width:0.5rem 0.5rem 0.5rem 0;border-right-color:#fff}.bs-popover-bottom,.bs-popover-auto[x-placement^="bottom"]{margin-top:0.5rem}.bs-popover-bottom>.arrow,.bs-popover-auto[x-placement^="bottom"]>.arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.arrow::before,.bs-popover-auto[x-placement^="bottom"]>.arrow::before{top:0;border-width:0 0.5rem 0.5rem 0.5rem;border-bottom-color:rgba(0,0,0,0.25)}.bs-popover-bottom>.arrow::after,.bs-popover-auto[x-placement^="bottom"]>.arrow::after{top:1px;border-width:0 0.5rem 0.5rem 0.5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[x-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-left,.bs-popover-auto[x-placement^="left"]{margin-right:0.5rem}.bs-popover-left>.arrow,.bs-popover-auto[x-placement^="left"]>.arrow{right:calc(-0.5rem - 1px);width:0.5rem;height:1rem;margin:0.3rem 0}.bs-popover-left>.arrow::before,.bs-popover-auto[x-placement^="left"]>.arrow::before{right:0;border-width:0.5rem 0 0.5rem 0.5rem;border-left-color:rgba(0,0,0,0.25)}.bs-popover-left>.arrow::after,.bs-popover-auto[x-placement^="left"]>.arrow::after{right:1px;border-width:0.5rem 0 0.5rem 0.5rem;border-left-color:#fff}.popover-header{padding:0.5rem 0.75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:0.5rem 0.75rem;color:#333}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:-webkit-transform 0.6s ease-in-out;transition:-webkit-transform 0.6s ease-in-out;transition:transform 0.6s ease-in-out;transition:transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out}@media (prefers-reduced-motion: reduce){.carousel-item{-webkit-transition:none;transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-left),.active.carousel-item-right{-webkit-transform:translateX(100%);transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-right),.active.carousel-item-left{-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;-webkit-transition:opacity 0s 0.6s;transition:opacity 0s 0.6s}@media (prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{-webkit-transition:none;transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:0.5;-webkit-transition:opacity 0.15s ease;transition:opacity 0.15s ease}@media (prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{-webkit-transition:none;transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:0.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50% / 100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{-webkit-box-sizing:content-box;box-sizing:content-box;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;-webkit-transition:opacity 0.6s ease;transition:opacity 0.6s ease}@media (prefers-reduced-motion: reduce){.carousel-indicators li{-webkit-transition:none;transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:0.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:0.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.bg-primary{background-color:#E95420 !important}a.bg-primary:hover,a.bg-primary:focus,button.bg-primary:hover,button.bg-primary:focus{background-color:#c34113 !important}.bg-secondary{background-color:#AEA79F !important}a.bg-secondary:hover,a.bg-secondary:focus,button.bg-secondary:hover,button.bg-secondary:focus{background-color:#978e83 !important}.bg-success{background-color:#38B44A !important}a.bg-success:hover,a.bg-success:focus,button.bg-success:hover,button.bg-success:focus{background-color:#2c8d3a !important}.bg-info{background-color:#17a2b8 !important}a.bg-info:hover,a.bg-info:focus,button.bg-info:hover,button.bg-info:focus{background-color:#117a8b !important}.bg-warning{background-color:#EFB73E !important}a.bg-warning:hover,a.bg-warning:focus,button.bg-warning:hover,button.bg-warning:focus{background-color:#e7a413 !important}.bg-danger{background-color:#DF382C !important}a.bg-danger:hover,a.bg-danger:focus,button.bg-danger:hover,button.bg-danger:focus{background-color:#bc271c !important}.bg-light{background-color:#e9ecef !important}a.bg-light:hover,a.bg-light:focus,button.bg-light:hover,button.bg-light:focus{background-color:#cbd3da !important}.bg-dark{background-color:#772953 !important}a.bg-dark:hover,a.bg-dark:focus,button.bg-dark:hover,button.bg-dark:focus{background-color:#511c39 !important}.bg-white{background-color:#fff !important}.bg-transparent{background-color:transparent !important}.border{border:1px solid #dee2e6 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-right{border-right:1px solid #dee2e6 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-left{border-left:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.border-primary{border-color:#E95420 !important}.border-secondary{border-color:#AEA79F !important}.border-success{border-color:#38B44A !important}.border-info{border-color:#17a2b8 !important}.border-warning{border-color:#EFB73E !important}.border-danger{border-color:#DF382C !important}.border-light{border-color:#e9ecef !important}.border-dark{border-color:#772953 !important}.border-white{border-color:#fff !important}.rounded-sm{border-radius:0.2rem !important}.rounded{border-radius:0.25rem !important}.rounded-top{border-top-left-radius:0.25rem !important;border-top-right-radius:0.25rem !important}.rounded-right{border-top-right-radius:0.25rem !important;border-bottom-right-radius:0.25rem !important}.rounded-bottom{border-bottom-right-radius:0.25rem !important;border-bottom-left-radius:0.25rem !important}.rounded-left{border-top-left-radius:0.25rem !important;border-bottom-left-radius:0.25rem !important}.rounded-lg{border-radius:0.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-0{border-radius:0 !important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}@media (min-width: 576px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-sm-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 768px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-md-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 992px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-lg-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media (min-width: 1200px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-xl-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important}.d-print-inline-flex{display:-webkit-inline-box !important;display:-ms-inline-flexbox !important;display:inline-flex !important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.8571428571%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}@media (min-width: 576px){.flex-sm-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-sm-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-sm-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-sm-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-sm-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-sm-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-sm-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-sm-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-sm-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-sm-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-sm-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-sm-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-sm-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-sm-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-sm-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-sm-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-sm-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-sm-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-sm-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-sm-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-sm-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-sm-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-sm-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-sm-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-sm-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-sm-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-sm-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-sm-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-sm-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-sm-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-sm-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-sm-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-sm-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 768px){.flex-md-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-md-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-md-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-md-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-md-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-md-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-md-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-md-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-md-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-md-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-md-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-md-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-md-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-md-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-md-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-md-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-md-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-md-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-md-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-md-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-md-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-md-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-md-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-md-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-md-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-md-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-md-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-md-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-md-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-md-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-md-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-md-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-md-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 992px){.flex-lg-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-lg-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-lg-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-lg-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-lg-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-lg-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-lg-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-lg-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-lg-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-lg-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-lg-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-lg-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-lg-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-lg-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-lg-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-lg-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-lg-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-lg-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-lg-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-lg-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-lg-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-lg-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-lg-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-lg-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-lg-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-lg-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-lg-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-lg-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-lg-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-lg-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-lg-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-lg-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-lg-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}@media (min-width: 1200px){.flex-xl-row{-webkit-box-orient:horizontal !important;-webkit-box-direction:normal !important;-ms-flex-direction:row !important;flex-direction:row !important}.flex-xl-column{-webkit-box-orient:vertical !important;-webkit-box-direction:normal !important;-ms-flex-direction:column !important;flex-direction:column !important}.flex-xl-row-reverse{-webkit-box-orient:horizontal !important;-webkit-box-direction:reverse !important;-ms-flex-direction:row-reverse !important;flex-direction:row-reverse !important}.flex-xl-column-reverse{-webkit-box-orient:vertical !important;-webkit-box-direction:reverse !important;-ms-flex-direction:column-reverse !important;flex-direction:column-reverse !important}.flex-xl-wrap{-ms-flex-wrap:wrap !important;flex-wrap:wrap !important}.flex-xl-nowrap{-ms-flex-wrap:nowrap !important;flex-wrap:nowrap !important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse !important;flex-wrap:wrap-reverse !important}.flex-xl-fill{-webkit-box-flex:1 !important;-ms-flex:1 1 auto !important;flex:1 1 auto !important}.flex-xl-grow-0{-webkit-box-flex:0 !important;-ms-flex-positive:0 !important;flex-grow:0 !important}.flex-xl-grow-1{-webkit-box-flex:1 !important;-ms-flex-positive:1 !important;flex-grow:1 !important}.flex-xl-shrink-0{-ms-flex-negative:0 !important;flex-shrink:0 !important}.flex-xl-shrink-1{-ms-flex-negative:1 !important;flex-shrink:1 !important}.justify-content-xl-start{-webkit-box-pack:start !important;-ms-flex-pack:start !important;justify-content:flex-start !important}.justify-content-xl-end{-webkit-box-pack:end !important;-ms-flex-pack:end !important;justify-content:flex-end !important}.justify-content-xl-center{-webkit-box-pack:center !important;-ms-flex-pack:center !important;justify-content:center !important}.justify-content-xl-between{-webkit-box-pack:justify !important;-ms-flex-pack:justify !important;justify-content:space-between !important}.justify-content-xl-around{-ms-flex-pack:distribute !important;justify-content:space-around !important}.align-items-xl-start{-webkit-box-align:start !important;-ms-flex-align:start !important;align-items:flex-start !important}.align-items-xl-end{-webkit-box-align:end !important;-ms-flex-align:end !important;align-items:flex-end !important}.align-items-xl-center{-webkit-box-align:center !important;-ms-flex-align:center !important;align-items:center !important}.align-items-xl-baseline{-webkit-box-align:baseline !important;-ms-flex-align:baseline !important;align-items:baseline !important}.align-items-xl-stretch{-webkit-box-align:stretch !important;-ms-flex-align:stretch !important;align-items:stretch !important}.align-content-xl-start{-ms-flex-line-pack:start !important;align-content:flex-start !important}.align-content-xl-end{-ms-flex-line-pack:end !important;align-content:flex-end !important}.align-content-xl-center{-ms-flex-line-pack:center !important;align-content:center !important}.align-content-xl-between{-ms-flex-line-pack:justify !important;align-content:space-between !important}.align-content-xl-around{-ms-flex-line-pack:distribute !important;align-content:space-around !important}.align-content-xl-stretch{-ms-flex-line-pack:stretch !important;align-content:stretch !important}.align-self-xl-auto{-ms-flex-item-align:auto !important;align-self:auto !important}.align-self-xl-start{-ms-flex-item-align:start !important;align-self:flex-start !important}.align-self-xl-end{-ms-flex-item-align:end !important;align-self:flex-end !important}.align-self-xl-center{-ms-flex-item-align:center !important;align-self:center !important}.align-self-xl-baseline{-ms-flex-item-align:baseline !important;align-self:baseline !important}.align-self-xl-stretch{-ms-flex-item-align:stretch !important;align-self:stretch !important}}.float-left{float:left !important}.float-right{float:right !important}.float-none{float:none !important}@media (min-width: 576px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media (min-width: 768px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media (min-width: 992px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media (min-width: 1200px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:-webkit-sticky !important;position:sticky !important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position: -webkit-sticky) or (position: sticky){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{-webkit-box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important;box-shadow:0 0.125rem 0.25rem rgba(0,0,0,0.075) !important}.shadow{-webkit-box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important;box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.shadow-lg{-webkit-box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important;box-shadow:0 1rem 3rem rgba(0,0,0,0.175) !important}.shadow-none{-webkit-box-shadow:none !important;box-shadow:none !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.min-vw-100{min-width:100vw !important}.min-vh-100{min-height:100vh !important}.vw-100{width:100vw !important}.vh-100{height:100vh !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:0.25rem !important}.mt-1,.my-1{margin-top:0.25rem !important}.mr-1,.mx-1{margin-right:0.25rem !important}.mb-1,.my-1{margin-bottom:0.25rem !important}.ml-1,.mx-1{margin-left:0.25rem !important}.m-2{margin:0.5rem !important}.mt-2,.my-2{margin-top:0.5rem !important}.mr-2,.mx-2{margin-right:0.5rem !important}.mb-2,.my-2{margin-bottom:0.5rem !important}.ml-2,.mx-2{margin-left:0.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:0.25rem !important}.pt-1,.py-1{padding-top:0.25rem !important}.pr-1,.px-1{padding-right:0.25rem !important}.pb-1,.py-1{padding-bottom:0.25rem !important}.pl-1,.px-1{padding-left:0.25rem !important}.p-2{padding:0.5rem !important}.pt-2,.py-2{padding-top:0.5rem !important}.pr-2,.px-2{padding-right:0.5rem !important}.pb-2,.py-2{padding-bottom:0.5rem !important}.pl-2,.px-2{padding-left:0.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-n1{margin:-0.25rem !important}.mt-n1,.my-n1{margin-top:-0.25rem !important}.mr-n1,.mx-n1{margin-right:-0.25rem !important}.mb-n1,.my-n1{margin-bottom:-0.25rem !important}.ml-n1,.mx-n1{margin-left:-0.25rem !important}.m-n2{margin:-0.5rem !important}.mt-n2,.my-n2{margin-top:-0.5rem !important}.mr-n2,.mx-n2{margin-right:-0.5rem !important}.mb-n2,.my-n2{margin-bottom:-0.5rem !important}.ml-n2,.mx-n2{margin-left:-0.5rem !important}.m-n3{margin:-1rem !important}.mt-n3,.my-n3{margin-top:-1rem !important}.mr-n3,.mx-n3{margin-right:-1rem !important}.mb-n3,.my-n3{margin-bottom:-1rem !important}.ml-n3,.mx-n3{margin-left:-1rem !important}.m-n4{margin:-1.5rem !important}.mt-n4,.my-n4{margin-top:-1.5rem !important}.mr-n4,.mx-n4{margin-right:-1.5rem !important}.mb-n4,.my-n4{margin-bottom:-1.5rem !important}.ml-n4,.mx-n4{margin-left:-1.5rem !important}.m-n5{margin:-3rem !important}.mt-n5,.my-n5{margin-top:-3rem !important}.mr-n5,.mx-n5{margin-right:-3rem !important}.mb-n5,.my-n5{margin-bottom:-3rem !important}.ml-n5,.mx-n5{margin-left:-3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media (min-width: 576px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:0.25rem !important}.mt-sm-1,.my-sm-1{margin-top:0.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:0.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:0.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:0.25rem !important}.m-sm-2{margin:0.5rem !important}.mt-sm-2,.my-sm-2{margin-top:0.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:0.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:0.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:0.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:0.25rem !important}.pt-sm-1,.py-sm-1{padding-top:0.25rem !important}.pr-sm-1,.px-sm-1{padding-right:0.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:0.25rem !important}.pl-sm-1,.px-sm-1{padding-left:0.25rem !important}.p-sm-2{padding:0.5rem !important}.pt-sm-2,.py-sm-2{padding-top:0.5rem !important}.pr-sm-2,.px-sm-2{padding-right:0.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:0.5rem !important}.pl-sm-2,.px-sm-2{padding-left:0.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-n1{margin:-0.25rem !important}.mt-sm-n1,.my-sm-n1{margin-top:-0.25rem !important}.mr-sm-n1,.mx-sm-n1{margin-right:-0.25rem !important}.mb-sm-n1,.my-sm-n1{margin-bottom:-0.25rem !important}.ml-sm-n1,.mx-sm-n1{margin-left:-0.25rem !important}.m-sm-n2{margin:-0.5rem !important}.mt-sm-n2,.my-sm-n2{margin-top:-0.5rem !important}.mr-sm-n2,.mx-sm-n2{margin-right:-0.5rem !important}.mb-sm-n2,.my-sm-n2{margin-bottom:-0.5rem !important}.ml-sm-n2,.mx-sm-n2{margin-left:-0.5rem !important}.m-sm-n3{margin:-1rem !important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem !important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem !important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem !important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem !important}.m-sm-n4{margin:-1.5rem !important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem !important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem !important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem !important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem !important}.m-sm-n5{margin:-3rem !important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem !important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem !important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem !important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:0.25rem !important}.mt-md-1,.my-md-1{margin-top:0.25rem !important}.mr-md-1,.mx-md-1{margin-right:0.25rem !important}.mb-md-1,.my-md-1{margin-bottom:0.25rem !important}.ml-md-1,.mx-md-1{margin-left:0.25rem !important}.m-md-2{margin:0.5rem !important}.mt-md-2,.my-md-2{margin-top:0.5rem !important}.mr-md-2,.mx-md-2{margin-right:0.5rem !important}.mb-md-2,.my-md-2{margin-bottom:0.5rem !important}.ml-md-2,.mx-md-2{margin-left:0.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:0.25rem !important}.pt-md-1,.py-md-1{padding-top:0.25rem !important}.pr-md-1,.px-md-1{padding-right:0.25rem !important}.pb-md-1,.py-md-1{padding-bottom:0.25rem !important}.pl-md-1,.px-md-1{padding-left:0.25rem !important}.p-md-2{padding:0.5rem !important}.pt-md-2,.py-md-2{padding-top:0.5rem !important}.pr-md-2,.px-md-2{padding-right:0.5rem !important}.pb-md-2,.py-md-2{padding-bottom:0.5rem !important}.pl-md-2,.px-md-2{padding-left:0.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-n1{margin:-0.25rem !important}.mt-md-n1,.my-md-n1{margin-top:-0.25rem !important}.mr-md-n1,.mx-md-n1{margin-right:-0.25rem !important}.mb-md-n1,.my-md-n1{margin-bottom:-0.25rem !important}.ml-md-n1,.mx-md-n1{margin-left:-0.25rem !important}.m-md-n2{margin:-0.5rem !important}.mt-md-n2,.my-md-n2{margin-top:-0.5rem !important}.mr-md-n2,.mx-md-n2{margin-right:-0.5rem !important}.mb-md-n2,.my-md-n2{margin-bottom:-0.5rem !important}.ml-md-n2,.mx-md-n2{margin-left:-0.5rem !important}.m-md-n3{margin:-1rem !important}.mt-md-n3,.my-md-n3{margin-top:-1rem !important}.mr-md-n3,.mx-md-n3{margin-right:-1rem !important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem !important}.ml-md-n3,.mx-md-n3{margin-left:-1rem !important}.m-md-n4{margin:-1.5rem !important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem !important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem !important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem !important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem !important}.m-md-n5{margin:-3rem !important}.mt-md-n5,.my-md-n5{margin-top:-3rem !important}.mr-md-n5,.mx-md-n5{margin-right:-3rem !important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem !important}.ml-md-n5,.mx-md-n5{margin-left:-3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media (min-width: 992px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:0.25rem !important}.mt-lg-1,.my-lg-1{margin-top:0.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:0.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:0.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:0.25rem !important}.m-lg-2{margin:0.5rem !important}.mt-lg-2,.my-lg-2{margin-top:0.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:0.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:0.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:0.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:0.25rem !important}.pt-lg-1,.py-lg-1{padding-top:0.25rem !important}.pr-lg-1,.px-lg-1{padding-right:0.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:0.25rem !important}.pl-lg-1,.px-lg-1{padding-left:0.25rem !important}.p-lg-2{padding:0.5rem !important}.pt-lg-2,.py-lg-2{padding-top:0.5rem !important}.pr-lg-2,.px-lg-2{padding-right:0.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:0.5rem !important}.pl-lg-2,.px-lg-2{padding-left:0.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-n1{margin:-0.25rem !important}.mt-lg-n1,.my-lg-n1{margin-top:-0.25rem !important}.mr-lg-n1,.mx-lg-n1{margin-right:-0.25rem !important}.mb-lg-n1,.my-lg-n1{margin-bottom:-0.25rem !important}.ml-lg-n1,.mx-lg-n1{margin-left:-0.25rem !important}.m-lg-n2{margin:-0.5rem !important}.mt-lg-n2,.my-lg-n2{margin-top:-0.5rem !important}.mr-lg-n2,.mx-lg-n2{margin-right:-0.5rem !important}.mb-lg-n2,.my-lg-n2{margin-bottom:-0.5rem !important}.ml-lg-n2,.mx-lg-n2{margin-left:-0.5rem !important}.m-lg-n3{margin:-1rem !important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem !important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem !important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem !important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem !important}.m-lg-n4{margin:-1.5rem !important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem !important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem !important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem !important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem !important}.m-lg-n5{margin:-3rem !important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem !important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem !important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem !important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media (min-width: 1200px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:0.25rem !important}.mt-xl-1,.my-xl-1{margin-top:0.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:0.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:0.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:0.25rem !important}.m-xl-2{margin:0.5rem !important}.mt-xl-2,.my-xl-2{margin-top:0.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:0.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:0.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:0.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:0.25rem !important}.pt-xl-1,.py-xl-1{padding-top:0.25rem !important}.pr-xl-1,.px-xl-1{padding-right:0.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:0.25rem !important}.pl-xl-1,.px-xl-1{padding-left:0.25rem !important}.p-xl-2{padding:0.5rem !important}.pt-xl-2,.py-xl-2{padding-top:0.5rem !important}.pr-xl-2,.px-xl-2{padding-right:0.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:0.5rem !important}.pl-xl-2,.px-xl-2{padding-left:0.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-n1{margin:-0.25rem !important}.mt-xl-n1,.my-xl-n1{margin-top:-0.25rem !important}.mr-xl-n1,.mx-xl-n1{margin-right:-0.25rem !important}.mb-xl-n1,.my-xl-n1{margin-bottom:-0.25rem !important}.ml-xl-n1,.mx-xl-n1{margin-left:-0.25rem !important}.m-xl-n2{margin:-0.5rem !important}.mt-xl-n2,.my-xl-n2{margin-top:-0.5rem !important}.mr-xl-n2,.mx-xl-n2{margin-right:-0.5rem !important}.mb-xl-n2,.my-xl-n2{margin-bottom:-0.5rem !important}.ml-xl-n2,.mx-xl-n2{margin-left:-0.5rem !important}.m-xl-n3{margin:-1rem !important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem !important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem !important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem !important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem !important}.m-xl-n4{margin:-1.5rem !important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem !important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem !important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem !important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem !important}.m-xl-n5{margin:-3rem !important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem !important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem !important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem !important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.text-monospace{font-family:SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important}.text-justify{text-align:justify !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}@media (min-width: 576px){.text-sm-left{text-align:left !important}.text-sm-right{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.text-md-left{text-align:left !important}.text-md-right{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.text-lg-left{text-align:left !important}.text-lg-right{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.text-xl-left{text-align:left !important}.text-xl-right{text-align:right !important}.text-xl-center{text-align:center !important}}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.font-weight-light{font-weight:300 !important}.font-weight-lighter{font-weight:lighter !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-weight-bolder{font-weight:bolder !important}.font-italic{font-style:italic !important}.text-white{color:#fff !important}.text-primary{color:#E95420 !important}a.text-primary:hover,a.text-primary:focus{color:#ac3911 !important}.text-secondary{color:#AEA79F !important}a.text-secondary:hover,a.text-secondary:focus{color:#8b8176 !important}.text-success{color:#38B44A !important}a.text-success:hover,a.text-success:focus{color:#267a32 !important}.text-info{color:#17a2b8 !important}a.text-info:hover,a.text-info:focus{color:#0f6674 !important}.text-warning{color:#EFB73E !important}a.text-warning:hover,a.text-warning:focus{color:#cf9311 !important}.text-danger{color:#DF382C !important}a.text-danger:hover,a.text-danger:focus{color:#a52219 !important}.text-light{color:#e9ecef !important}a.text-light:hover,a.text-light:focus{color:#bdc6cf !important}.text-dark{color:#772953 !important}a.text-dark:hover,a.text-dark:focus{color:#3e152b !important}.text-body{color:#333 !important}.text-muted{color:#868e96 !important}.text-black-50{color:rgba(0,0,0,0.5) !important}.text-white-50{color:rgba(255,255,255,0.5) !important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none !important}.text-break{word-break:break-word !important;overflow-wrap:break-word !important}.text-reset{color:inherit !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media print{*,*::before,*::after{text-shadow:none !important;-webkit-box-shadow:none !important;box-shadow:none !important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap !important}pre,blockquote{border:1px solid #AEA79F;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px !important}.container{min-width:992px !important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #dee2e6 !important}.table-dark{color:inherit}.table-dark th,.table-dark td,.table-dark thead th,.table-dark tbody+tbody{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} diff --git a/css/bootstrap.min.css.old2 b/css/bootstrap.min.css.old2 new file mode 100755 index 0000000..2f48c7f --- /dev/null +++ b/css/bootstrap.min.css.old2 @@ -0,0 +1 @@ +:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.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-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.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-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.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-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:flex;flex:1 0 0%;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.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}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;align-items:center;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} \ No newline at end of file diff --git a/css/bootstrap.min.css.old3 b/css/bootstrap.min.css.old3 new file mode 100755 index 0000000..eb0d85a --- /dev/null +++ b/css/bootstrap.min.css.old3 @@ -0,0 +1,9279 @@ +:root { - + -blue: #446E9B; - + -indigo: #6610f2; - + -purple: #6f42c1; - + -pink: #e83e8c; - + -red: #CD0200; - + -orange: #fd7e14; - + -yellow: #D47500; - + -green: #3CB521; - + -teal: #20c997; - + -cyan: #3399F3; - + -white: #fff; - + -gray: #777; - + -gray-dark: #333; - + -primary: #446E9B; - + -secondary: #999; - + -success: #3CB521; - + -info: #3399F3; - + -warning: #D47500; - + -danger: #CD0200; - + -light: #eee; - + -dark: #333; - + -breakpoint-xs: 0; - + -breakpoint-sm: 576px; - + -breakpoint-md: 768px; - + -breakpoint-lg: 992px; - + -breakpoint-xl: 1200px; - + -font-family-sans-serif: "Open Sans", -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - + -font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace +} + +*, ::after, ::before { + box-sizing: border-box +} + +html { + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent +} + +article, aside, figcaption, figure, footer, header, hgroup, main, nav, + section { + display: block +} + +body { + margin: 0; + font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", + Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #777; + text-align: left; + background-color: #fff +} + +[tabindex="-1"]:focus { + outline: 0 !important +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: .5rem +} + +p { + margin-top: 0; + margin-bottom: 1rem +} + +abbr[data-original-title], abbr[title] { + text-decoration: underline; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; + text-decoration-skip-ink: none +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit +} + +dl, ol, ul { + margin-top: 0; + margin-bottom: 1rem +} + +ol ol, ol ul, ul ol, ul ul { + margin-bottom: 0 +} + +dt { + font-weight: 700 +} + +dd { + margin-bottom: .5rem; + margin-left: 0 +} + +blockquote { + margin: 0 0 1rem +} + +b, strong { + font-weight: bolder +} + +small { + font-size: 80% +} + +sub, sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +a { + color: #446E9B; + text-decoration: none; + background-color: transparent +} + +a:hover { + color: #0c73cd; + text-decoration: underline +} + +a:not ([href] ):not ([tabindex] ){ + color: inherit; + text-decoration: none +} + +a:not ([href] ):not ([tabindex] ):focus, a:not ([href] ):not ([tabindex] + ):hover { + color: inherit; + text-decoration: none +} + +a:not ([href] ):not ([tabindex] ):focus { + outline: 0 +} + +code, kbd, pre, samp { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", + "Courier New", monospace; + font-size: 1em +} + +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto +} + +figure { + margin: 0 0 1rem +} + +img { + vertical-align: middle; + border-style: none +} + +svg { + overflow: hidden; + vertical-align: middle +} + +table { + border-collapse: collapse +} + +caption { + padding-top: .75rem; + padding-bottom: .75rem; + color: #777; + text-align: left; + caption-side: bottom +} + +th { + text-align: inherit +} + +label { + display: inline-block; + margin-bottom: .5rem +} + +button { + border-radius: 0 +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color +} + +button, input, optgroup, select, textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit +} + +button, input { + overflow: visible +} + +button, select { + text-transform: none +} + +select { + word-wrap: normal +} + +[type=button], [type=reset], [type=submit], button { + -webkit-appearance: button +} + +[type=button]:not (:disabled ), [type=reset]:not (:disabled ), [type=submit]:not + (:disabled ), button:not (:disabled ){ + cursor: pointer +} + +[type=button]::-moz-focus-inner, [type=reset]::-moz-focus-inner, [type=submit]::-moz-focus-inner, + button::-moz-focus-inner { + padding: 0; + border-style: none +} + +input[type=checkbox], input[type=radio] { + box-sizing: border-box; + padding: 0 +} + +input[type=date], input[type=datetime-local], input[type=month], input[type=time] + { + -webkit-appearance: listbox +} + +textarea { + overflow: auto; + resize: vertical +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0 +} + +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal +} + +progress { + vertical-align: baseline +} + +[type=number]::-webkit-inner-spin-button, [type=number]::-webkit-outer-spin-button + { + height: auto +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: none +} + +[type=search]::-webkit-search-decoration { + -webkit-appearance: none +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button +} + +output { + display: inline-block +} + +summary { + display: list-item; + cursor: pointer +} + +template { + display: none +} + +[hidden] { + display: none !important +} + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + margin-bottom: .5rem; + font-weight: 500; + line-height: 1.2; + color: #2d2d2d +} + +.h1, h1 { + font-size: 2.5rem +} + +.h2, h2 { + font-size: 2rem +} + +.h3, h3 { + font-size: 1.75rem +} + +.h4, h4 { + font-size: 1.5rem +} + +.h5, h5 { + font-size: 1.25rem +} + +.h6, h6 { + font-size: 1rem +} + +.lead { + font-size: 1.25rem; + font-weight: 300 +} + +.display-1 { + font-size: 6rem; + font-weight: 300; + line-height: 1.2 +} + +.display-2 { + font-size: 5.5rem; + font-weight: 300; + line-height: 1.2 +} + +.display-3 { + font-size: 4.5rem; + font-weight: 300; + line-height: 1.2 +} + +.display-4 { + font-size: 3.5rem; + font-weight: 300; + line-height: 1.2 +} + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, .1) +} + +.small, small { + font-size: 80%; + font-weight: 400 +} + +.mark, mark { + padding: .2em; + background-color: #fcf8e3 +} + +.list-unstyled { + padding-left: 0; + list-style: none +} + +.list-inline { + padding-left: 0; + list-style: none +} + +.list-inline-item { + display: inline-block +} + +.list-inline-item:not (:last-child ){ + margin-right: .5rem +} + +.initialism { + font-size: 90%; + text-transform: uppercase +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem +} + +.blockquote-footer { + display: block; + font-size: 80%; + color: #777 +} + +.blockquote-footer::before { + content: "\2014\00A0" +} + +.img-fluid { + max-width: 100%; + height: auto +} + +.img-thumbnail { + padding: .25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: .25rem; + max-width: 100%; + height: auto +} + +.figure { + display: inline-block +} + +.figure-img { + margin-bottom: .5rem; + line-height: 1 +} + +.figure-caption { + font-size: 90%; + color: #777 +} + +code { + font-size: 87.5%; + color: #e83e8c; + word-break: break-word +} + +a>code { + color: inherit +} + +kbd { + padding: .2rem .4rem; + font-size: 87.5%; + color: #fff; + background-color: #2d2d2d; + border-radius: .2rem +} + +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: 700 +} + +pre { + display: block; + font-size: 87.5%; + color: #2d2d2d +} + +pre code { + font-size: inherit; + color: inherit; + word-break: normal +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto +} + +@media ( min-width :576px) { + .container { + max-width: 540px + } +} + +@media ( min-width :768px) { + .container { + max-width: 720px + } +} + +@media ( min-width :992px) { + .container { + max-width: 960px + } +} + +@media ( min-width :1200px) { + .container { + max-width: 1140px + } +} + +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto +} + +.row { + display: flex; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px +} + +.no-gutters { + margin-right: 0; + margin-left: 0 +} + +.no-gutters>.col, .no-gutters>[class*=col-] { + padding-right: 0; + padding-left: 0 +} + +.col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, + .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, + .col-lg-10, .col-lg-11, .col-lg-12, .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-auto, + .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .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-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, + .col-sm-12, .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-auto, .col-xl, .col-xl-1, + .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, + .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto { + position: relative; + width: 100%; + padding-right: 15px; + padding-left: 15px +} + +.col { + flex-basis: 0; + flex-grow: 1; + max-width: 100% +} + +.col-auto { + flex: 0 0 auto; + width: auto; + max-width: 100% +} + +.col-1 { + flex: 0 0 8.33333%; + max-width: 8.33333% +} + +.col-2 { + flex: 0 0 16.66667%; + max-width: 16.66667% +} + +.col-3 { + flex: 0 0 25%; + max-width: 25% +} + +.col-4 { + flex: 0 0 33.33333%; + max-width: 33.33333% +} + +.col-5 { + flex: 0 0 41.66667%; + max-width: 41.66667% +} + +.col-6 { + flex: 0 0 50%; + max-width: 50% +} + +.col-7 { + flex: 0 0 58.33333%; + max-width: 58.33333% +} + +.col-8 { + flex: 0 0 66.66667%; + max-width: 66.66667% +} + +.col-9 { + flex: 0 0 75%; + max-width: 75% +} + +.col-10 { + flex: 0 0 83.33333%; + max-width: 83.33333% +} + +.col-11 { + flex: 0 0 91.66667%; + max-width: 91.66667% +} + +.col-12 { + flex: 0 0 100%; + max-width: 100% +} + +.order-first { + order: -1 +} + +.order-last { + order: 13 +} + +.order-0 { + order: 0 +} + +.order-1 { + order: 1 +} + +.order-2 { + order: 2 +} + +.order-3 { + order: 3 +} + +.order-4 { + order: 4 +} + +.order-5 { + order: 5 +} + +.order-6 { + order: 6 +} + +.order-7 { + order: 7 +} + +.order-8 { + order: 8 +} + +.order-9 { + order: 9 +} + +.order-10 { + order: 10 +} + +.order-11 { + order: 11 +} + +.order-12 { + order: 12 +} + +.offset-1 { + margin-left: 8.33333% +} + +.offset-2 { + margin-left: 16.66667% +} + +.offset-3 { + margin-left: 25% +} + +.offset-4 { + margin-left: 33.33333% +} + +.offset-5 { + margin-left: 41.66667% +} + +.offset-6 { + margin-left: 50% +} + +.offset-7 { + margin-left: 58.33333% +} + +.offset-8 { + margin-left: 66.66667% +} + +.offset-9 { + margin-left: 75% +} + +.offset-10 { + margin-left: 83.33333% +} + +.offset-11 { + margin-left: 91.66667% +} + +@media ( min-width :576px) { + .col-sm { + flex-basis: 0; + flex-grow: 1; + max-width: 100% + } + .col-sm-auto { + flex: 0 0 auto; + width: auto; + max-width: 100% + } + .col-sm-1 { + flex: 0 0 8.33333%; + max-width: 8.33333% + } + .col-sm-2 { + flex: 0 0 16.66667%; + max-width: 16.66667% + } + .col-sm-3 { + flex: 0 0 25%; + max-width: 25% + } + .col-sm-4 { + flex: 0 0 33.33333%; + max-width: 33.33333% + } + .col-sm-5 { + flex: 0 0 41.66667%; + max-width: 41.66667% + } + .col-sm-6 { + flex: 0 0 50%; + max-width: 50% + } + .col-sm-7 { + flex: 0 0 58.33333%; + max-width: 58.33333% + } + .col-sm-8 { + flex: 0 0 66.66667%; + max-width: 66.66667% + } + .col-sm-9 { + flex: 0 0 75%; + max-width: 75% + } + .col-sm-10 { + flex: 0 0 83.33333%; + max-width: 83.33333% + } + .col-sm-11 { + flex: 0 0 91.66667%; + max-width: 91.66667% + } + .col-sm-12 { + flex: 0 0 100%; + max-width: 100% + } + .order-sm-first { + order: -1 + } + .order-sm-last { + order: 13 + } + .order-sm-0 { + order: 0 + } + .order-sm-1 { + order: 1 + } + .order-sm-2 { + order: 2 + } + .order-sm-3 { + order: 3 + } + .order-sm-4 { + order: 4 + } + .order-sm-5 { + order: 5 + } + .order-sm-6 { + order: 6 + } + .order-sm-7 { + order: 7 + } + .order-sm-8 { + order: 8 + } + .order-sm-9 { + order: 9 + } + .order-sm-10 { + order: 10 + } + .order-sm-11 { + order: 11 + } + .order-sm-12 { + order: 12 + } + .offset-sm-0 { + margin-left: 0 + } + .offset-sm-1 { + margin-left: 8.33333% + } + .offset-sm-2 { + margin-left: 16.66667% + } + .offset-sm-3 { + margin-left: 25% + } + .offset-sm-4 { + margin-left: 33.33333% + } + .offset-sm-5 { + margin-left: 41.66667% + } + .offset-sm-6 { + margin-left: 50% + } + .offset-sm-7 { + margin-left: 58.33333% + } + .offset-sm-8 { + margin-left: 66.66667% + } + .offset-sm-9 { + margin-left: 75% + } + .offset-sm-10 { + margin-left: 83.33333% + } + .offset-sm-11 { + margin-left: 91.66667% + } +} + +@media ( min-width :768px) { + .col-md { + flex-basis: 0; + flex-grow: 1; + max-width: 100% + } + .col-md-auto { + flex: 0 0 auto; + width: auto; + max-width: 100% + } + .col-md-1 { + flex: 0 0 8.33333%; + max-width: 8.33333% + } + .col-md-2 { + flex: 0 0 16.66667%; + max-width: 16.66667% + } + .col-md-3 { + flex: 0 0 25%; + max-width: 25% + } + .col-md-4 { + flex: 0 0 33.33333%; + max-width: 33.33333% + } + .col-md-5 { + flex: 0 0 41.66667%; + max-width: 41.66667% + } + .col-md-6 { + flex: 0 0 50%; + max-width: 50% + } + .col-md-7 { + flex: 0 0 58.33333%; + max-width: 58.33333% + } + .col-md-8 { + flex: 0 0 66.66667%; + max-width: 66.66667% + } + .col-md-9 { + flex: 0 0 75%; + max-width: 75% + } + .col-md-10 { + flex: 0 0 83.33333%; + max-width: 83.33333% + } + .col-md-11 { + flex: 0 0 91.66667%; + max-width: 91.66667% + } + .col-md-12 { + flex: 0 0 100%; + max-width: 100% + } + .order-md-first { + order: -1 + } + .order-md-last { + order: 13 + } + .order-md-0 { + order: 0 + } + .order-md-1 { + order: 1 + } + .order-md-2 { + order: 2 + } + .order-md-3 { + order: 3 + } + .order-md-4 { + order: 4 + } + .order-md-5 { + order: 5 + } + .order-md-6 { + order: 6 + } + .order-md-7 { + order: 7 + } + .order-md-8 { + order: 8 + } + .order-md-9 { + order: 9 + } + .order-md-10 { + order: 10 + } + .order-md-11 { + order: 11 + } + .order-md-12 { + order: 12 + } + .offset-md-0 { + margin-left: 0 + } + .offset-md-1 { + margin-left: 8.33333% + } + .offset-md-2 { + margin-left: 16.66667% + } + .offset-md-3 { + margin-left: 25% + } + .offset-md-4 { + margin-left: 33.33333% + } + .offset-md-5 { + margin-left: 41.66667% + } + .offset-md-6 { + margin-left: 50% + } + .offset-md-7 { + margin-left: 58.33333% + } + .offset-md-8 { + margin-left: 66.66667% + } + .offset-md-9 { + margin-left: 75% + } + .offset-md-10 { + margin-left: 83.33333% + } + .offset-md-11 { + margin-left: 91.66667% + } +} + +@media ( min-width :992px) { + .col-lg { + flex-basis: 0; + flex-grow: 1; + max-width: 100% + } + .col-lg-auto { + flex: 0 0 auto; + width: auto; + max-width: 100% + } + .col-lg-1 { + flex: 0 0 8.33333%; + max-width: 8.33333% + } + .col-lg-2 { + flex: 0 0 16.66667%; + max-width: 16.66667% + } + .col-lg-3 { + flex: 0 0 25%; + max-width: 25% + } + .col-lg-4 { + flex: 0 0 33.33333%; + max-width: 33.33333% + } + .col-lg-5 { + flex: 0 0 41.66667%; + max-width: 41.66667% + } + .col-lg-6 { + flex: 0 0 50%; + max-width: 50% + } + .col-lg-7 { + flex: 0 0 58.33333%; + max-width: 58.33333% + } + .col-lg-8 { + flex: 0 0 66.66667%; + max-width: 66.66667% + } + .col-lg-9 { + flex: 0 0 75%; + max-width: 75% + } + .col-lg-10 { + flex: 0 0 83.33333%; + max-width: 83.33333% + } + .col-lg-11 { + flex: 0 0 91.66667%; + max-width: 91.66667% + } + .col-lg-12 { + flex: 0 0 100%; + max-width: 100% + } + .order-lg-first { + order: -1 + } + .order-lg-last { + order: 13 + } + .order-lg-0 { + order: 0 + } + .order-lg-1 { + order: 1 + } + .order-lg-2 { + order: 2 + } + .order-lg-3 { + order: 3 + } + .order-lg-4 { + order: 4 + } + .order-lg-5 { + order: 5 + } + .order-lg-6 { + order: 6 + } + .order-lg-7 { + order: 7 + } + .order-lg-8 { + order: 8 + } + .order-lg-9 { + order: 9 + } + .order-lg-10 { + order: 10 + } + .order-lg-11 { + order: 11 + } + .order-lg-12 { + order: 12 + } + .offset-lg-0 { + margin-left: 0 + } + .offset-lg-1 { + margin-left: 8.33333% + } + .offset-lg-2 { + margin-left: 16.66667% + } + .offset-lg-3 { + margin-left: 25% + } + .offset-lg-4 { + margin-left: 33.33333% + } + .offset-lg-5 { + margin-left: 41.66667% + } + .offset-lg-6 { + margin-left: 50% + } + .offset-lg-7 { + margin-left: 58.33333% + } + .offset-lg-8 { + margin-left: 66.66667% + } + .offset-lg-9 { + margin-left: 75% + } + .offset-lg-10 { + margin-left: 83.33333% + } + .offset-lg-11 { + margin-left: 91.66667% + } +} + +@media ( min-width :1200px) { + .col-xl { + flex-basis: 0; + flex-grow: 1; + max-width: 100% + } + .col-xl-auto { + flex: 0 0 auto; + width: auto; + max-width: 100% + } + .col-xl-1 { + flex: 0 0 8.33333%; + max-width: 8.33333% + } + .col-xl-2 { + flex: 0 0 16.66667%; + max-width: 16.66667% + } + .col-xl-3 { + flex: 0 0 25%; + max-width: 25% + } + .col-xl-4 { + flex: 0 0 33.33333%; + max-width: 33.33333% + } + .col-xl-5 { + flex: 0 0 41.66667%; + max-width: 41.66667% + } + .col-xl-6 { + flex: 0 0 50%; + max-width: 50% + } + .col-xl-7 { + flex: 0 0 58.33333%; + max-width: 58.33333% + } + .col-xl-8 { + flex: 0 0 66.66667%; + max-width: 66.66667% + } + .col-xl-9 { + flex: 0 0 75%; + max-width: 75% + } + .col-xl-10 { + flex: 0 0 83.33333%; + max-width: 83.33333% + } + .col-xl-11 { + flex: 0 0 91.66667%; + max-width: 91.66667% + } + .col-xl-12 { + flex: 0 0 100%; + max-width: 100% + } + .order-xl-first { + order: -1 + } + .order-xl-last { + order: 13 + } + .order-xl-0 { + order: 0 + } + .order-xl-1 { + order: 1 + } + .order-xl-2 { + order: 2 + } + .order-xl-3 { + order: 3 + } + .order-xl-4 { + order: 4 + } + .order-xl-5 { + order: 5 + } + .order-xl-6 { + order: 6 + } + .order-xl-7 { + order: 7 + } + .order-xl-8 { + order: 8 + } + .order-xl-9 { + order: 9 + } + .order-xl-10 { + order: 10 + } + .order-xl-11 { + order: 11 + } + .order-xl-12 { + order: 12 + } + .offset-xl-0 { + margin-left: 0 + } + .offset-xl-1 { + margin-left: 8.33333% + } + .offset-xl-2 { + margin-left: 16.66667% + } + .offset-xl-3 { + margin-left: 25% + } + .offset-xl-4 { + margin-left: 33.33333% + } + .offset-xl-5 { + margin-left: 41.66667% + } + .offset-xl-6 { + margin-left: 50% + } + .offset-xl-7 { + margin-left: 58.33333% + } + .offset-xl-8 { + margin-left: 66.66667% + } + .offset-xl-9 { + margin-left: 75% + } + .offset-xl-10 { + margin-left: 83.33333% + } + .offset-xl-11 { + margin-left: 91.66667% + } +} + +.table { + width: 100%; + margin-bottom: 1rem; + color: #777 +} + +.table td, .table th { + padding: .75rem; + vertical-align: top; + border-top: 1px solid #dee2e6 +} + +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6 +} + +.table tbody+tbody { + border-top: 2px solid #dee2e6 +} + +.table-sm td, .table-sm th { + padding: .3rem +} + +.table-bordered { + border: 1px solid #dee2e6 +} + +.table-bordered td, .table-bordered th { + border: 1px solid #dee2e6 +} + +.table-bordered thead td, .table-bordered thead th { + border-bottom-width: 2px +} + +.table-borderless tbody+tbody, .table-borderless td, .table-borderless th, + .table-borderless thead th { + border: 0 +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, .05) +} + +.table-hover tbody tr:hover { + color: #777; + background-color: rgba(0, 0, 0, .075) +} + +.table-primary, .table-primary>td, .table-primary>th { + background-color: #cbd6e3 +} + +.table-primary tbody+tbody, .table-primary td, .table-primary th, + .table-primary thead th { + border-color: #9eb4cb +} + +.table-hover .table-primary:hover { + background-color: #bac9da +} + +.table-hover .table-primary:hover>td, .table-hover .table-primary:hover>th + { + background-color: #bac9da +} + +.table-secondary, .table-secondary>td, .table-secondary>th { + background-color: #e2e2e2 +} + +.table-secondary tbody+tbody, .table-secondary td, .table-secondary th, + .table-secondary thead th { + border-color: #cacaca +} + +.table-hover .table-secondary:hover { + background-color: #d5d5d5 +} + +.table-hover .table-secondary:hover>td, .table-hover .table-secondary:hover>th + { + background-color: #d5d5d5 +} + +.table-success, .table-success>td, .table-success>th { + background-color: #c8eac1 +} + +.table-success tbody+tbody, .table-success td, .table-success th, + .table-success thead th { + border-color: #9ad98c +} + +.table-hover .table-success:hover { + background-color: #b7e4ae +} + +.table-hover .table-success:hover>td, .table-hover .table-success:hover>th + { + background-color: #b7e4ae +} + +.table-info, .table-info>td, .table-info>th { + background-color: #c6e2fc +} + +.table-info tbody+tbody, .table-info td, .table-info th, .table-info thead th + { + border-color: #95caf9 +} + +.table-hover .table-info:hover { + background-color: #aed6fb +} + +.table-hover .table-info:hover>td, .table-hover .table-info:hover>th { + background-color: #aed6fb +} + +.table-warning, .table-warning>td, .table-warning>th { + background-color: #f3d8b8 +} + +.table-warning tbody+tbody, .table-warning td, .table-warning th, + .table-warning thead th { + border-color: #e9b77a +} + +.table-hover .table-warning:hover { + background-color: #efcca2 +} + +.table-hover .table-warning:hover>td, .table-hover .table-warning:hover>th + { + background-color: #efcca2 +} + +.table-danger, .table-danger>td, .table-danger>th { + background-color: #f1b8b8 +} + +.table-danger tbody+tbody, .table-danger td, .table-danger th, + .table-danger thead th { + border-color: #e57b7a +} + +.table-hover .table-danger:hover { + background-color: #eda3a3 +} + +.table-hover .table-danger:hover>td, .table-hover .table-danger:hover>th + { + background-color: #eda3a3 +} + +.table-light, .table-light>td, .table-light>th { + background-color: #fafafa +} + +.table-light tbody+tbody, .table-light td, .table-light th, .table-light thead th + { + border-color: #f6f6f6 +} + +.table-hover .table-light:hover { + background-color: #ededed +} + +.table-hover .table-light:hover>td, .table-hover .table-light:hover>th { + background-color: #ededed +} + +.table-dark, .table-dark>td, .table-dark>th { + background-color: #c6c6c6 +} + +.table-dark tbody+tbody, .table-dark td, .table-dark th, .table-dark thead th + { + border-color: #959595 +} + +.table-hover .table-dark:hover { + background-color: #b9b9b9 +} + +.table-hover .table-dark:hover>td, .table-hover .table-dark:hover>th { + background-color: #b9b9b9 +} + +.table-active, .table-active>td, .table-active>th { + background-color: rgba(0, 0, 0, .075) +} + +.table-hover .table-active:hover { + background-color: rgba(0, 0, 0, .075) +} + +.table-hover .table-active:hover>td, .table-hover .table-active:hover>th + { + background-color: rgba(0, 0, 0, .075) +} + +.table .thead-dark th { + color: #fff; + background-color: #333; + border-color: #464646 +} + +.table .thead-light th { + color: #495057; + background-color: #eee; + border-color: #dee2e6 +} + +.table-dark { + color: #fff; + background-color: #333 +} + +.table-dark td, .table-dark th, .table-dark thead th { + border-color: #464646 +} + +.table-dark.table-bordered { + border: 0 +} + +.table-dark.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(255, 255, 255, .05) +} + +.table-dark.table-hover tbody tr:hover { + color: #fff; + background-color: rgba(255, 255, 255, .075) +} + +@media ( max-width :575.98px) { + .table-responsive-sm { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch + } + .table-responsive-sm>.table-bordered { + border: 0 + } +} + +@media ( max-width :767.98px) { + .table-responsive-md { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch + } + .table-responsive-md>.table-bordered { + border: 0 + } +} + +@media ( max-width :991.98px) { + .table-responsive-lg { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch + } + .table-responsive-lg>.table-bordered { + border: 0 + } +} + +@media ( max-width :1199.98px) { + .table-responsive-xl { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch + } + .table-responsive-xl>.table-bordered { + border: 0 + } +} + +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch +} + +.table-responsive>.table-bordered { + border: 0 +} + +.form-control { + display: block; + width: 100%; + height: calc(1.5em + .75rem + 2px); + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: .25rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media ( prefers-reduced-motion :reduce) { + .form-control { + transition: none + } +} + +.form-control::-ms-expand { + background-color: transparent; + border: 0 +} + +.form-control:focus { + color: #495057; + background-color: #fff; + border-color: #90aece; + outline: 0; + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.form-control::placeholder { + color: #777; + opacity: 1 +} + +.form-control:disabled, .form-control[readonly] { + background-color: #eee; + opacity: 1 +} + +select.form-control:focus::-ms-value { + color: #495057; + background-color: #fff +} + +.form-control-file, .form-control-range { + display: block; + width: 100% +} + +.col-form-label { + padding-top: calc(.375rem + 1px); + padding-bottom: calc(.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5 +} + +.col-form-label-lg { + padding-top: calc(.5rem + 1px); + padding-bottom: calc(.5rem + 1px); + font-size: 1.25rem; + line-height: 1.5 +} + +.col-form-label-sm { + padding-top: calc(.25rem + 1px); + padding-bottom: calc(.25rem + 1px); + font-size: .875rem; + line-height: 1.5 +} + +.form-control-plaintext { + display: block; + width: 100%; + padding-top: .375rem; + padding-bottom: .375rem; + margin-bottom: 0; + line-height: 1.5; + color: #777; + background-color: transparent; + border: solid transparent; + border-width: 1px 0 +} + +.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm + { + padding-right: 0; + padding-left: 0 +} + +.form-control-sm { + height: calc(1.5em + .5rem + 2px); + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.5; + border-radius: .2rem +} + +.form-control-lg { + height: calc(1.5em + 1rem + 2px); + padding: .5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: .3rem +} + +select.form-control[multiple], select.form-control[size] { + height: auto +} + +textarea.form-control { + height: auto +} + +.form-group { + margin-bottom: 1rem +} + +.form-text { + display: block; + margin-top: .25rem +} + +.form-row { + display: flex; + flex-wrap: wrap; + margin-right: -5px; + margin-left: -5px +} + +.form-row>.col, .form-row>[class*=col-] { + padding-right: 5px; + padding-left: 5px +} + +.form-check { + position: relative; + display: block; + padding-left: 1.25rem +} + +.form-check-input { + position: absolute; + margin-top: .3rem; + margin-left: -1.25rem +} + +.form-check-input:disabled ~.form-check-label { + color: #777 +} + +.form-check-label { + margin-bottom: 0 +} + +.form-check-inline { + display: inline-flex; + align-items: center; + padding-left: 0; + margin-right: .75rem +} + +.form-check-inline .form-check-input { + position: static; + margin-top: 0; + margin-right: .3125rem; + margin-left: 0 +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: 80%; + color: #3cb521 +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1.5; + color: #fff; + background-color: rgba(60, 181, 33, .9); + border-radius: .25rem +} + +.form-control.is-valid, .was-validated .form-control:valid { + border-color: #3cb521; + padding-right: calc(1.5em + .75rem); + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233CB521' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: center right calc(.375em + .1875rem); + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-control.is-valid:focus, .was-validated .form-control:valid:focus { + border-color: #3cb521; + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .25) +} + +.form-control.is-valid ~.valid-feedback, .form-control.is-valid ~.valid-tooltip, + .was-validated .form-control:valid ~.valid-feedback, .was-validated .form-control:valid + ~.valid-tooltip { + display: block +} + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid + { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right + calc(.375em + .1875rem) +} + +.custom-select.is-valid, .was-validated .custom-select:valid { + border-color: #3cb521; + padding-right: calc(( 1em + .75rem)* 3/4+ 1.75rem); + background: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") + no-repeat right .75rem center/8px 10px, + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233CB521' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") + #fff no-repeat center right 1.75rem/calc(.75em + .375rem) + calc(.75em + .375rem) +} + +.custom-select.is-valid:focus, .was-validated .custom-select:valid:focus + { + border-color: #3cb521; + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .25) +} + +.custom-select.is-valid ~.valid-feedback, .custom-select.is-valid ~.valid-tooltip, + .was-validated .custom-select:valid ~.valid-feedback, .was-validated .custom-select:valid + ~.valid-tooltip { + display: block +} + +.form-control-file.is-valid ~.valid-feedback, .form-control-file.is-valid + ~.valid-tooltip, .was-validated .form-control-file:valid ~.valid-feedback, + .was-validated .form-control-file:valid ~.valid-tooltip { + display: block +} + +.form-check-input.is-valid ~.form-check-label, .was-validated .form-check-input:valid + ~.form-check-label { + color: #3cb521 +} + +.form-check-input.is-valid ~.valid-feedback, .form-check-input.is-valid + ~.valid-tooltip, .was-validated .form-check-input:valid ~.valid-feedback, + .was-validated .form-check-input:valid ~.valid-tooltip { + display: block +} + +.custom-control-input.is-valid ~.custom-control-label, .was-validated .custom-control-input:valid + ~.custom-control-label { + color: #3cb521 +} + +.custom-control-input.is-valid ~.custom-control-label::before, + .was-validated .custom-control-input:valid ~.custom-control-label::before + { + border-color: #3cb521 +} + +.custom-control-input.is-valid ~.valid-feedback, .custom-control-input.is-valid + ~.valid-tooltip, .was-validated .custom-control-input:valid ~.valid-feedback, + .was-validated .custom-control-input:valid ~.valid-tooltip { + display: block +} + +.custom-control-input.is-valid:checked ~.custom-control-label::before, + .was-validated .custom-control-input:valid:checked ~.custom-control-label::before + { + border-color: #4fd930; + background-color: #4fd930 +} + +.custom-control-input.is-valid:focus ~.custom-control-label::before, + .was-validated .custom-control-input:valid:focus ~.custom-control-label::before + { + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .25) +} + +.custom-control-input.is-valid:focus:not (:checked )~.custom-control-label::before, + .was-validated .custom-control-input:valid:focus:not (:checked )~.custom-control-label::before + { + border-color: #3cb521 +} + +.custom-file-input.is-valid ~.custom-file-label, .was-validated .custom-file-input:valid + ~.custom-file-label { + border-color: #3cb521 +} + +.custom-file-input.is-valid ~.valid-feedback, .custom-file-input.is-valid + ~.valid-tooltip, .was-validated .custom-file-input:valid ~.valid-feedback, + .was-validated .custom-file-input:valid ~.valid-tooltip { + display: block +} + +.custom-file-input.is-valid:focus ~.custom-file-label, .was-validated .custom-file-input:valid:focus + ~.custom-file-label { + border-color: #3cb521; + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .25) +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: 80%; + color: #cd0200 +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1.5; + color: #fff; + background-color: rgba(205, 2, 0, .9); + border-radius: .25rem +} + +.form-control.is-invalid, .was-validated .form-control:invalid { + border-color: #cd0200; + padding-right: calc(1.5em + .75rem); + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23CD0200' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23CD0200' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E"); + background-repeat: no-repeat; + background-position: center right calc(.375em + .1875rem); + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-control.is-invalid:focus, .was-validated .form-control:invalid:focus + { + border-color: #cd0200; + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .25) +} + +.form-control.is-invalid ~.invalid-feedback, .form-control.is-invalid ~.invalid-tooltip, + .was-validated .form-control:invalid ~.invalid-feedback, .was-validated .form-control:invalid + ~.invalid-tooltip { + display: block +} + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid + { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right + calc(.375em + .1875rem) +} + +.custom-select.is-invalid, .was-validated .custom-select:invalid { + border-color: #cd0200; + padding-right: calc(( 1em + .75rem)* 3/4+ 1.75rem); + background: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") + no-repeat right .75rem center/8px 10px, + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23CD0200' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23CD0200' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") + #fff no-repeat center right 1.75rem/calc(.75em + .375rem) + calc(.75em + .375rem) +} + +.custom-select.is-invalid:focus, .was-validated .custom-select:invalid:focus + { + border-color: #cd0200; + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .25) +} + +.custom-select.is-invalid ~.invalid-feedback, .custom-select.is-invalid + ~.invalid-tooltip, .was-validated .custom-select:invalid ~.invalid-feedback, + .was-validated .custom-select:invalid ~.invalid-tooltip { + display: block +} + +.form-control-file.is-invalid ~.invalid-feedback, .form-control-file.is-invalid + ~.invalid-tooltip, .was-validated .form-control-file:invalid ~.invalid-feedback, + .was-validated .form-control-file:invalid ~.invalid-tooltip { + display: block +} + +.form-check-input.is-invalid ~.form-check-label, .was-validated .form-check-input:invalid + ~.form-check-label { + color: #cd0200 +} + +.form-check-input.is-invalid ~.invalid-feedback, .form-check-input.is-invalid + ~.invalid-tooltip, .was-validated .form-check-input:invalid ~.invalid-feedback, + .was-validated .form-check-input:invalid ~.invalid-tooltip { + display: block +} + +.custom-control-input.is-invalid ~.custom-control-label, .was-validated .custom-control-input:invalid + ~.custom-control-label { + color: #cd0200 +} + +.custom-control-input.is-invalid ~.custom-control-label::before, + .was-validated .custom-control-input:invalid ~.custom-control-label::before + { + border-color: #cd0200 +} + +.custom-control-input.is-invalid ~.invalid-feedback, + .custom-control-input.is-invalid ~.invalid-tooltip, .was-validated .custom-control-input:invalid + ~.invalid-feedback, .was-validated .custom-control-input:invalid ~.invalid-tooltip + { + display: block +} + +.custom-control-input.is-invalid:checked ~.custom-control-label::before, + .was-validated .custom-control-input:invalid:checked ~.custom-control-label::before + { + border-color: #ff0301; + background-color: #ff0301 +} + +.custom-control-input.is-invalid:focus ~.custom-control-label::before, + .was-validated .custom-control-input:invalid:focus ~.custom-control-label::before + { + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .25) +} + +.custom-control-input.is-invalid:focus:not (:checked )~.custom-control-label::before, + .was-validated .custom-control-input:invalid:focus:not (:checked )~.custom-control-label::before + { + border-color: #cd0200 +} + +.custom-file-input.is-invalid ~.custom-file-label, .was-validated .custom-file-input:invalid + ~.custom-file-label { + border-color: #cd0200 +} + +.custom-file-input.is-invalid ~.invalid-feedback, .custom-file-input.is-invalid + ~.invalid-tooltip, .was-validated .custom-file-input:invalid ~.invalid-feedback, + .was-validated .custom-file-input:invalid ~.invalid-tooltip { + display: block +} + +.custom-file-input.is-invalid:focus ~.custom-file-label, .was-validated .custom-file-input:invalid:focus + ~.custom-file-label { + border-color: #cd0200; + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .25) +} + +.form-inline { + display: flex; + flex-flow: row wrap; + align-items: center +} + +.form-inline .form-check { + width: 100% +} + +@media ( min-width :576px) { + .form-inline label { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 0 + } + .form-inline .form-group { + display: flex; + flex: 0 0 auto; + flex-flow: row wrap; + align-items: center; + margin-bottom: 0 + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle + } + .form-inline .form-control-plaintext { + display: inline-block + } + .form-inline .custom-select, .form-inline .input-group { + width: auto + } + .form-inline .form-check { + display: flex; + align-items: center; + justify-content: center; + width: auto; + padding-left: 0 + } + .form-inline .form-check-input { + position: relative; + flex-shrink: 0; + margin-top: 0; + margin-right: .25rem; + margin-left: 0 + } + .form-inline .custom-control { + align-items: center; + justify-content: center + } + .form-inline .custom-control-label { + margin-bottom: 0 + } +} + +.btn { + display: inline-block; + font-weight: 400; + color: #777; + text-align: center; + vertical-align: middle; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: .375rem .75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: .25rem; + transition: color .15s ease-in-out, background-color .15s ease-in-out, + border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media ( prefers-reduced-motion :reduce) { + .btn { + transition: none + } +} + +.btn:hover { + color: #777; + text-decoration: none +} + +.btn.focus, .btn:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.btn.disabled, .btn:disabled { + opacity: .65 +} + +a.btn.disabled, fieldset:disabled a.btn { + pointer-events: none +} + +.btn-primary { + color: #fff; + background-color: #446e9b; + border-color: #446e9b +} + +.btn-primary:hover { + color: #fff; + background-color: #385b80; + border-color: #345578 +} + +.btn-primary.focus, .btn-primary:focus { + box-shadow: 0 0 0 .2rem rgba(96, 132, 170, .5) +} + +.btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #446e9b; + border-color: #446e9b +} + +.btn-primary:not (:disabled ):not (.disabled ).active, .btn-primary:not + (:disabled ):not (.disabled ):active, .show>.btn-primary.dropdown-toggle + { + color: #fff; + background-color: #345578; + border-color: #314f6f +} + +.btn-primary:not (:disabled ):not (.disabled ).active:focus, + .btn-primary:not (:disabled ):not (.disabled ):active:focus, .show>.btn-primary.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(96, 132, 170, .5) +} + +.btn-secondary { + color: #fff; + background-color: #999; + border-color: #999 +} + +.btn-secondary:hover { + color: #fff; + background-color: #868686; + border-color: gray +} + +.btn-secondary.focus, .btn-secondary:focus { + box-shadow: 0 0 0 .2rem rgba(168, 168, 168, .5) +} + +.btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #999; + border-color: #999 +} + +.btn-secondary:not (:disabled ):not (.disabled ).active, .btn-secondary:not + (:disabled ):not (.disabled ):active, .show>.btn-secondary.dropdown-toggle + { + color: #fff; + background-color: gray; + border-color: #797979 +} + +.btn-secondary:not (:disabled ):not (.disabled ).active:focus, + .btn-secondary:not (:disabled ):not (.disabled ):active:focus, .show>.btn-secondary.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(168, 168, 168, .5) +} + +.btn-success { + color: #fff; + background-color: #3cb521; + border-color: #3cb521 +} + +.btn-success:hover { + color: #fff; + background-color: #31951b; + border-color: #2e8a19 +} + +.btn-success.focus, .btn-success:focus { + box-shadow: 0 0 0 .2rem rgba(89, 192, 66, .5) +} + +.btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #3cb521; + border-color: #3cb521 +} + +.btn-success:not (:disabled ):not (.disabled ).active, .btn-success:not + (:disabled ):not (.disabled ):active, .show>.btn-success.dropdown-toggle + { + color: #fff; + background-color: #2e8a19; + border-color: #2a7f17 +} + +.btn-success:not (:disabled ):not (.disabled ).active:focus, + .btn-success:not (:disabled ):not (.disabled ):active:focus, .show>.btn-success.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(89, 192, 66, .5) +} + +.btn-info { + color: #fff; + background-color: #3399f3; + border-color: #3399f3 +} + +.btn-info:hover { + color: #fff; + background-color: #0f87f1; + border-color: #0e80e6 +} + +.btn-info.focus, .btn-info:focus { + box-shadow: 0 0 0 .2rem rgba(82, 168, 245, .5) +} + +.btn-info.disabled, .btn-info:disabled { + color: #fff; + background-color: #3399f3; + border-color: #3399f3 +} + +.btn-info:not (:disabled ):not (.disabled ).active, .btn-info:not (:disabled + ):not (.disabled ):active, .show>.btn-info.dropdown-toggle { + color: #fff; + background-color: #0e80e6; + border-color: #0d7ad9 +} + +.btn-info:not (:disabled ):not (.disabled ).active:focus, .btn-info:not + (:disabled ):not (.disabled ):active:focus, .show>.btn-info.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(82, 168, 245, .5) +} + +.btn-warning { + color: #fff; + background-color: #d47500; + border-color: #d47500 +} + +.btn-warning:hover { + color: #fff; + background-color: #ae6000; + border-color: #a15900 +} + +.btn-warning.focus, .btn-warning:focus { + box-shadow: 0 0 0 .2rem rgba(218, 138, 38, .5) +} + +.btn-warning.disabled, .btn-warning:disabled { + color: #fff; + background-color: #d47500; + border-color: #d47500 +} + +.btn-warning:not (:disabled ):not (.disabled ).active, .btn-warning:not + (:disabled ):not (.disabled ):active, .show>.btn-warning.dropdown-toggle + { + color: #fff; + background-color: #a15900; + border-color: #945200 +} + +.btn-warning:not (:disabled ):not (.disabled ).active:focus, + .btn-warning:not (:disabled ):not (.disabled ):active:focus, .show>.btn-warning.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(218, 138, 38, .5) +} + +.btn-danger { + color: #fff; + background-color: #cd0200; + border-color: #cd0200 +} + +.btn-danger:hover { + color: #fff; + background-color: #a70200; + border-color: #9a0200 +} + +.btn-danger.focus, .btn-danger:focus { + box-shadow: 0 0 0 .2rem rgba(213, 40, 38, .5) +} + +.btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #cd0200; + border-color: #cd0200 +} + +.btn-danger:not (:disabled ):not (.disabled ).active, .btn-danger:not (:disabled + ):not (.disabled ):active, .show>.btn-danger.dropdown-toggle { + color: #fff; + background-color: #9a0200; + border-color: #8d0100 +} + +.btn-danger:not (:disabled ):not (.disabled ).active:focus, .btn-danger:not + (:disabled ):not (.disabled ):active:focus, .show>.btn-danger.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(213, 40, 38, .5) +} + +.btn-light { + color: #2d2d2d; + background-color: #eee; + border-color: #eee +} + +.btn-light:hover { + color: #2d2d2d; + background-color: #dbdbdb; + border-color: #d5d5d5 +} + +.btn-light.focus, .btn-light:focus { + box-shadow: 0 0 0 .2rem rgba(209, 209, 209, .5) +} + +.btn-light.disabled, .btn-light:disabled { + color: #2d2d2d; + background-color: #eee; + border-color: #eee +} + +.btn-light:not (:disabled ):not (.disabled ).active, .btn-light:not (:disabled + ):not (.disabled ):active, .show>.btn-light.dropdown-toggle { + color: #2d2d2d; + background-color: #d5d5d5; + border-color: #cecece +} + +.btn-light:not (:disabled ):not (.disabled ).active:focus, .btn-light:not + (:disabled ):not (.disabled ):active:focus, .show>.btn-light.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(209, 209, 209, .5) +} + +.btn-dark { + color: #fff; + background-color: #333; + border-color: #333 +} + +.btn-dark:hover { + color: #fff; + background-color: #202020; + border-color: #1a1a1a +} + +.btn-dark.focus, .btn-dark:focus { + box-shadow: 0 0 0 .2rem rgba(82, 82, 82, .5) +} + +.btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #333; + border-color: #333 +} + +.btn-dark:not (:disabled ):not (.disabled ).active, .btn-dark:not (:disabled + ):not (.disabled ):active, .show>.btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1a1a; + border-color: #131313 +} + +.btn-dark:not (:disabled ):not (.disabled ).active:focus, .btn-dark:not + (:disabled ):not (.disabled ):active:focus, .show>.btn-dark.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(82, 82, 82, .5) +} + +.btn-outline-primary { + color: #446e9b; + border-color: #446e9b +} + +.btn-outline-primary:hover { + color: #fff; + background-color: #446e9b; + border-color: #446e9b +} + +.btn-outline-primary.focus, .btn-outline-primary:focus { + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .5) +} + +.btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #446e9b; + background-color: transparent +} + +.btn-outline-primary:not (:disabled ):not (.disabled ).active, + .btn-outline-primary:not (:disabled ):not (.disabled ):active, .show>.btn-outline-primary.dropdown-toggle + { + color: #fff; + background-color: #446e9b; + border-color: #446e9b +} + +.btn-outline-primary:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-primary:not (:disabled ):not (.disabled ):active:focus, + .show>.btn-outline-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .5) +} + +.btn-outline-secondary { + color: #999; + border-color: #999 +} + +.btn-outline-secondary:hover { + color: #fff; + background-color: #999; + border-color: #999 +} + +.btn-outline-secondary.focus, .btn-outline-secondary:focus { + box-shadow: 0 0 0 .2rem rgba(153, 153, 153, .5) +} + +.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #999; + background-color: transparent +} + +.btn-outline-secondary:not (:disabled ):not (.disabled ).active, + .btn-outline-secondary:not (:disabled ):not (.disabled ):active, .show>.btn-outline-secondary.dropdown-toggle + { + color: #fff; + background-color: #999; + border-color: #999 +} + +.btn-outline-secondary:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-secondary:not (:disabled ):not (.disabled ):active:focus, + .show>.btn-outline-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 .2rem rgba(153, 153, 153, .5) +} + +.btn-outline-success { + color: #3cb521; + border-color: #3cb521 +} + +.btn-outline-success:hover { + color: #fff; + background-color: #3cb521; + border-color: #3cb521 +} + +.btn-outline-success.focus, .btn-outline-success:focus { + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .5) +} + +.btn-outline-success.disabled, .btn-outline-success:disabled { + color: #3cb521; + background-color: transparent +} + +.btn-outline-success:not (:disabled ):not (.disabled ).active, + .btn-outline-success:not (:disabled ):not (.disabled ):active, .show>.btn-outline-success.dropdown-toggle + { + color: #fff; + background-color: #3cb521; + border-color: #3cb521 +} + +.btn-outline-success:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-success:not (:disabled ):not (.disabled ):active:focus, + .show>.btn-outline-success.dropdown-toggle:focus { + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .5) +} + +.btn-outline-info { + color: #3399f3; + border-color: #3399f3 +} + +.btn-outline-info:hover { + color: #fff; + background-color: #3399f3; + border-color: #3399f3 +} + +.btn-outline-info.focus, .btn-outline-info:focus { + box-shadow: 0 0 0 .2rem rgba(51, 153, 243, .5) +} + +.btn-outline-info.disabled, .btn-outline-info:disabled { + color: #3399f3; + background-color: transparent +} + +.btn-outline-info:not (:disabled ):not (.disabled ).active, + .btn-outline-info:not (:disabled ):not (.disabled ):active, .show>.btn-outline-info.dropdown-toggle + { + color: #fff; + background-color: #3399f3; + border-color: #3399f3 +} + +.btn-outline-info:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-info:not (:disabled ):not (.disabled ):active:focus, .show>.btn-outline-info.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(51, 153, 243, .5) +} + +.btn-outline-warning { + color: #d47500; + border-color: #d47500 +} + +.btn-outline-warning:hover { + color: #fff; + background-color: #d47500; + border-color: #d47500 +} + +.btn-outline-warning.focus, .btn-outline-warning:focus { + box-shadow: 0 0 0 .2rem rgba(212, 117, 0, .5) +} + +.btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #d47500; + background-color: transparent +} + +.btn-outline-warning:not (:disabled ):not (.disabled ).active, + .btn-outline-warning:not (:disabled ):not (.disabled ):active, .show>.btn-outline-warning.dropdown-toggle + { + color: #fff; + background-color: #d47500; + border-color: #d47500 +} + +.btn-outline-warning:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-warning:not (:disabled ):not (.disabled ):active:focus, + .show>.btn-outline-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 .2rem rgba(212, 117, 0, .5) +} + +.btn-outline-danger { + color: #cd0200; + border-color: #cd0200 +} + +.btn-outline-danger:hover { + color: #fff; + background-color: #cd0200; + border-color: #cd0200 +} + +.btn-outline-danger.focus, .btn-outline-danger:focus { + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .5) +} + +.btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #cd0200; + background-color: transparent +} + +.btn-outline-danger:not (:disabled ):not (.disabled ).active, + .btn-outline-danger:not (:disabled ):not (.disabled ):active, .show>.btn-outline-danger.dropdown-toggle + { + color: #fff; + background-color: #cd0200; + border-color: #cd0200 +} + +.btn-outline-danger:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-danger:not (:disabled ):not (.disabled ):active:focus, + .show>.btn-outline-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .5) +} + +.btn-outline-light { + color: #eee; + border-color: #eee +} + +.btn-outline-light:hover { + color: #2d2d2d; + background-color: #eee; + border-color: #eee +} + +.btn-outline-light.focus, .btn-outline-light:focus { + box-shadow: 0 0 0 .2rem rgba(238, 238, 238, .5) +} + +.btn-outline-light.disabled, .btn-outline-light:disabled { + color: #eee; + background-color: transparent +} + +.btn-outline-light:not (:disabled ):not (.disabled ).active, + .btn-outline-light:not (:disabled ):not (.disabled ):active, .show>.btn-outline-light.dropdown-toggle + { + color: #2d2d2d; + background-color: #eee; + border-color: #eee +} + +.btn-outline-light:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-light:not (:disabled ):not (.disabled ):active:focus, + .show>.btn-outline-light.dropdown-toggle:focus { + box-shadow: 0 0 0 .2rem rgba(238, 238, 238, .5) +} + +.btn-outline-dark { + color: #333; + border-color: #333 +} + +.btn-outline-dark:hover { + color: #fff; + background-color: #333; + border-color: #333 +} + +.btn-outline-dark.focus, .btn-outline-dark:focus { + box-shadow: 0 0 0 .2rem rgba(51, 51, 51, .5) +} + +.btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #333; + background-color: transparent +} + +.btn-outline-dark:not (:disabled ):not (.disabled ).active, + .btn-outline-dark:not (:disabled ):not (.disabled ):active, .show>.btn-outline-dark.dropdown-toggle + { + color: #fff; + background-color: #333; + border-color: #333 +} + +.btn-outline-dark:not (:disabled ):not (.disabled ).active:focus, + .btn-outline-dark:not (:disabled ):not (.disabled ):active:focus, .show>.btn-outline-dark.dropdown-toggle:focus + { + box-shadow: 0 0 0 .2rem rgba(51, 51, 51, .5) +} + +.btn-link { + font-weight: 400; + color: #3399f3; + text-decoration: none +} + +.btn-link:hover { + color: #0c73cd; + text-decoration: underline +} + +.btn-link.focus, .btn-link:focus { + text-decoration: underline; + box-shadow: none +} + +.btn-link.disabled, .btn-link:disabled { + color: #777; + pointer-events: none +} + +.btn-group-lg>.btn, .btn-lg { + padding: .5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: .3rem +} + +.btn-group-sm>.btn, .btn-sm { + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.5; + border-radius: .2rem +} + +.btn-block { + display: block; + width: 100% +} + +.btn-block+.btn-block { + margin-top: .5rem +} + +input[type=button].btn-block, input[type=reset].btn-block, input[type=submit].btn-block + { + width: 100% +} + +.fade { + transition: opacity .15s linear +} + +@media ( prefers-reduced-motion :reduce) { + .fade { + transition: none + } +} + +.fade:not (.show ){ + opacity: 0 +} + +.collapse:not (.show ){ + display: none +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition: height .35s ease +} + +@media ( prefers-reduced-motion :reduce) { + .collapsing { + transition: none + } +} + +.dropdown, .dropleft, .dropright, .dropup { + position: relative +} + +.dropdown-toggle { + white-space: nowrap +} + +.dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent +} + +.dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: .5rem 0; + margin: .125rem 0 0; + font-size: 1rem; + color: #777; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: .25rem +} + +.dropdown-menu-left { + right: auto; + left: 0 +} + +.dropdown-menu-right { + right: 0; + left: auto +} + +@media ( min-width :576px) { + .dropdown-menu-sm-left { + right: auto; + left: 0 + } + .dropdown-menu-sm-right { + right: 0; + left: auto + } +} + +@media ( min-width :768px) { + .dropdown-menu-md-left { + right: auto; + left: 0 + } + .dropdown-menu-md-right { + right: 0; + left: auto + } +} + +@media ( min-width :992px) { + .dropdown-menu-lg-left { + right: auto; + left: 0 + } + .dropdown-menu-lg-right { + right: 0; + left: auto + } +} + +@media ( min-width :1200px) { + .dropdown-menu-xl-left { + right: auto; + left: 0 + } + .dropdown-menu-xl-right { + right: 0; + left: auto + } +} + +.dropup .dropdown-menu { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: .125rem +} + +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: 0; + border-right: .3em solid transparent; + border-bottom: .3em solid; + border-left: .3em solid transparent +} + +.dropup .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropright .dropdown-menu { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: .125rem +} + +.dropright .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: 0; + border-bottom: .3em solid transparent; + border-left: .3em solid +} + +.dropright .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropright .dropdown-toggle::after { + vertical-align: 0 +} + +.dropleft .dropdown-menu { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: .125rem +} + +.dropleft .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: "" +} + +.dropleft .dropdown-toggle::after { + display: none +} + +.dropleft .dropdown-toggle::before { + display: inline-block; + margin-right: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: .3em solid; + border-bottom: .3em solid transparent +} + +.dropleft .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropleft .dropdown-toggle::before { + vertical-align: 0 +} + +.dropdown-menu[x-placement^=bottom], .dropdown-menu[x-placement^=left], + .dropdown-menu[x-placement^=right], .dropdown-menu[x-placement^=top] { + right: auto; + bottom: auto +} + +.dropdown-divider { + height: 0; + margin: .5rem 0; + overflow: hidden; + border-top: 1px solid #eee +} + +.dropdown-item { + display: block; + width: 100%; + padding: .25rem 1.5rem; + clear: both; + font-weight: 400; + color: #2d2d2d; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0 +} + +.dropdown-item:focus, .dropdown-item:hover { + color: #202020; + text-decoration: none; + background-color: #f8f9fa +} + +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #446e9b +} + +.dropdown-item.disabled, .dropdown-item:disabled { + color: #777; + pointer-events: none; + background-color: transparent +} + +.dropdown-menu.show { + display: block +} + +.dropdown-header { + display: block; + padding: .5rem 1.5rem; + margin-bottom: 0; + font-size: .875rem; + color: #777; + white-space: nowrap +} + +.dropdown-item-text { + display: block; + padding: .25rem 1.5rem; + color: #2d2d2d +} + +.btn-group, .btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle +} + +.btn-group-vertical>.btn, .btn-group>.btn { + position: relative; + flex: 1 1 auto +} + +.btn-group-vertical>.btn:hover, .btn-group>.btn:hover { + z-index: 1 +} + +.btn-group-vertical>.btn.active, .btn-group-vertical>.btn:active, + .btn-group-vertical>.btn:focus, .btn-group>.btn.active, .btn-group>.btn:active, + .btn-group>.btn:focus { + z-index: 1 +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start +} + +.btn-toolbar .input-group { + width: auto +} + +.btn-group>.btn-group:not (:first-child ), .btn-group>.btn:not (:first-child + ){ + margin-left: -1px +} + +.btn-group>.btn-group:not (:last-child )>.btn, .btn-group>.btn:not (:last-child + ):not (.dropdown-toggle ){ + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group>.btn-group:not (:first-child )>.btn, .btn-group>.btn:not (:first-child + ){ + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.dropdown-toggle-split { + padding-right: .5625rem; + padding-left: .5625rem +} + +.dropdown-toggle-split::after, .dropright .dropdown-toggle-split::after, + .dropup .dropdown-toggle-split::after { + margin-left: 0 +} + +.dropleft .dropdown-toggle-split::before { + margin-right: 0 +} + +.btn-group-sm>.btn+.dropdown-toggle-split, .btn-sm+.dropdown-toggle-split + { + padding-right: .375rem; + padding-left: .375rem +} + +.btn-group-lg>.btn+.dropdown-toggle-split, .btn-lg+.dropdown-toggle-split + { + padding-right: .75rem; + padding-left: .75rem +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center +} + +.btn-group-vertical>.btn, .btn-group-vertical>.btn-group { + width: 100% +} + +.btn-group-vertical>.btn-group:not (:first-child ), .btn-group-vertical>.btn:not + (:first-child ){ + margin-top: -1px +} + +.btn-group-vertical>.btn-group:not (:last-child )>.btn, + .btn-group-vertical>.btn:not (:last-child ):not (.dropdown-toggle ){ + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical>.btn-group:not (:first-child )>.btn, + .btn-group-vertical>.btn:not (:first-child ){ + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.btn-group-toggle>.btn, .btn-group-toggle>.btn-group>.btn { + margin-bottom: 0 +} + +.btn-group-toggle>.btn input[type=checkbox], .btn-group-toggle>.btn input[type=radio], + .btn-group-toggle>.btn-group>.btn input[type=checkbox], + .btn-group-toggle>.btn-group>.btn input[type=radio] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100% +} + +.input-group>.custom-file, .input-group>.custom-select, .input-group>.form-control, + .input-group>.form-control-plaintext { + position: relative; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0 +} + +.input-group>.custom-file+.custom-file, .input-group>.custom-file+.custom-select, + .input-group>.custom-file+.form-control, .input-group>.custom-select+.custom-file, + .input-group>.custom-select+.custom-select, .input-group>.custom-select+.form-control, + .input-group>.form-control+.custom-file, .input-group>.form-control+.custom-select, + .input-group>.form-control+.form-control, .input-group>.form-control-plaintext+.custom-file, + .input-group>.form-control-plaintext+.custom-select, .input-group>.form-control-plaintext+.form-control + { + margin-left: -1px +} + +.input-group>.custom-file .custom-file-input:focus ~.custom-file-label, + .input-group>.custom-select:focus, .input-group>.form-control:focus { + z-index: 3 +} + +.input-group>.custom-file .custom-file-input:focus { + z-index: 4 +} + +.input-group>.custom-select:not (:last-child ), .input-group>.form-control:not + (:last-child ){ + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group>.custom-select:not (:first-child ), .input-group>.form-control:not + (:first-child ){ + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.input-group>.custom-file { + display: flex; + align-items: center +} + +.input-group>.custom-file:not (:last-child ) .custom-file-label, + .input-group>.custom-file:not (:last-child ) .custom-file-label::after + { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group>.custom-file:not (:first-child ) .custom-file-label { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.input-group-append, .input-group-prepend { + display: flex +} + +.input-group-append .btn, .input-group-prepend .btn { + position: relative; + z-index: 2 +} + +.input-group-append .btn:focus, .input-group-prepend .btn:focus { + z-index: 3 +} + +.input-group-append .btn+.btn, .input-group-append .btn+.input-group-text, + .input-group-append .input-group-text+.btn, .input-group-append .input-group-text+.input-group-text, + .input-group-prepend .btn+.btn, .input-group-prepend .btn+.input-group-text, + .input-group-prepend .input-group-text+.btn, .input-group-prepend .input-group-text+.input-group-text + { + margin-left: -1px +} + +.input-group-prepend { + margin-right: -1px +} + +.input-group-append { + margin-left: -1px +} + +.input-group-text { + display: flex; + align-items: center; + padding: .375rem .75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #eee; + border: 1px solid #ced4da; + border-radius: .25rem +} + +.input-group-text input[type=checkbox], .input-group-text input[type=radio] + { + margin-top: 0 +} + +.input-group-lg>.custom-select, .input-group-lg>.form-control:not(textarea) + { + height: calc(1.5em + 1rem + 2px) +} + +.input-group-lg>.custom-select, .input-group-lg>.form-control, + .input-group-lg>.input-group-append>.btn, .input-group-lg>.input-group-append>.input-group-text, + .input-group-lg>.input-group-prepend>.btn, .input-group-lg>.input-group-prepend>.input-group-text + { + padding: .5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: .3rem +} + +.input-group-sm>.custom-select, .input-group-sm>.form-control:not(textarea) + { + height: calc(1.5em + .5rem + 2px) +} + +.input-group-sm>.custom-select, .input-group-sm>.form-control, + .input-group-sm>.input-group-append>.btn, .input-group-sm>.input-group-append>.input-group-text, + .input-group-sm>.input-group-prepend>.btn, .input-group-sm>.input-group-prepend>.input-group-text + { + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.5; + border-radius: .2rem +} + +.input-group-lg>.custom-select, .input-group-sm>.custom-select { + padding-right: 1.75rem +} + +.input-group>.input-group-append:last-child>.btn:not (:last-child ):not + (.dropdown-toggle ), .input-group>.input-group-append:last-child>.input-group-text:not + (:last-child ), .input-group>.input-group-append:not (:last-child )>.btn, + .input-group>.input-group-append:not (:last-child )>.input-group-text, + .input-group>.input-group-prepend>.btn, .input-group>.input-group-prepend>.input-group-text + { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group>.input-group-append>.btn, .input-group>.input-group-append>.input-group-text, + .input-group>.input-group-prepend:first-child>.btn:not (:first-child ), + .input-group>.input-group-prepend:first-child>.input-group-text:not (:first-child + ), .input-group>.input-group-prepend:not (:first-child )>.btn, + .input-group>.input-group-prepend:not (:first-child )>.input-group-text + { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.custom-control { + position: relative; + display: block; + min-height: 1.5rem; + padding-left: 1.5rem +} + +.custom-control-inline { + display: inline-flex; + margin-right: 1rem +} + +.custom-control-input { + position: absolute; + z-index: -1; + opacity: 0 +} + +.custom-control-input:checked ~.custom-control-label::before { + color: #fff; + border-color: #446e9b; + background-color: #446e9b +} + +.custom-control-input:focus ~.custom-control-label::before { + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.custom-control-input:focus:not (:checked )~.custom-control-label::before + { + border-color: #90aece +} + +.custom-control-input:not (:disabled ):active ~.custom-control-label::before + { + color: #fff; + background-color: #b4c8de; + border-color: #b4c8de +} + +.custom-control-input:disabled ~.custom-control-label { + color: #777 +} + +.custom-control-input:disabled ~.custom-control-label::before { + background-color: #eee +} + +.custom-control-label { + position: relative; + margin-bottom: 0; + vertical-align: top +} + +.custom-control-label::before { + position: absolute; + top: .25rem; + left: -1.5rem; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ""; + background-color: #fff; + border: #999 solid 1px +} + +.custom-control-label::after { + position: absolute; + top: .25rem; + left: -1.5rem; + display: block; + width: 1rem; + height: 1rem; + content: ""; + background: no-repeat 50%/50% 50% +} + +.custom-checkbox .custom-control-label::before { + border-radius: .25rem +} + +.custom-checkbox .custom-control-input:checked ~.custom-control-label::after + { + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e") +} + +.custom-checkbox .custom-control-input:indeterminate ~.custom-control-label::before + { + border-color: #446e9b; + background-color: #446e9b +} + +.custom-checkbox .custom-control-input:indeterminate ~.custom-control-label::after + { + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e") +} + +.custom-checkbox .custom-control-input:disabled:checked ~.custom-control-label::before + { + background-color: rgba(68, 110, 155, .5) +} + +.custom-checkbox .custom-control-input:disabled:indeterminate ~.custom-control-label::before + { + background-color: rgba(68, 110, 155, .5) +} + +.custom-radio .custom-control-label::before { + border-radius: 50% +} + +.custom-radio .custom-control-input:checked ~.custom-control-label::after + { + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e") +} + +.custom-radio .custom-control-input:disabled:checked ~.custom-control-label::before + { + background-color: rgba(68, 110, 155, .5) +} + +.custom-switch { + padding-left: 2.25rem +} + +.custom-switch .custom-control-label::before { + left: -2.25rem; + width: 1.75rem; + pointer-events: all; + border-radius: .5rem +} + +.custom-switch .custom-control-label::after { + top: calc(.25rem + 2px); + left: calc(-2.25rem + 2px); + width: calc(1rem - 4px); + height: calc(1rem - 4px); + background-color: #999; + border-radius: .5rem; + transition: transform .15s ease-in-out, background-color .15s + ease-in-out, border-color .15s ease-in-out, box-shadow .15s + ease-in-out +} + +@media ( prefers-reduced-motion :reduce) { + .custom-switch .custom-control-label::after { + transition: none + } +} + +.custom-switch .custom-control-input:checked ~.custom-control-label::after + { + background-color: #fff; + transform: translateX(.75rem) +} + +.custom-switch .custom-control-input:disabled:checked ~.custom-control-label::before + { + background-color: rgba(68, 110, 155, .5) +} + +.custom-select { + display: inline-block; + width: 100%; + height: calc(1.5em + .75rem + 2px); + padding: .375rem 1.75rem .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") + no-repeat right .75rem center/8px 10px; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: .25rem; + appearance: none +} + +.custom-select:focus { + border-color: #90aece; + outline: 0; + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.custom-select:focus::-ms-value { + color: #495057; + background-color: #fff +} + +.custom-select[multiple], .custom-select[size]:not ([size="1"] ){ + height: auto; + padding-right: .75rem; + background-image: none +} + +.custom-select:disabled { + color: #777; + background-color: #eee +} + +.custom-select::-ms-expand { + display: none +} + +.custom-select-sm { + height: calc(1.5em + .5rem + 2px); + padding-top: .25rem; + padding-bottom: .25rem; + padding-left: .5rem; + font-size: .875rem +} + +.custom-select-lg { + height: calc(1.5em + 1rem + 2px); + padding-top: .5rem; + padding-bottom: .5rem; + padding-left: 1rem; + font-size: 1.25rem +} + +.custom-file { + position: relative; + display: inline-block; + width: 100%; + height: calc(1.5em + .75rem + 2px); + margin-bottom: 0 +} + +.custom-file-input { + position: relative; + z-index: 2; + width: 100%; + height: calc(1.5em + .75rem + 2px); + margin: 0; + opacity: 0 +} + +.custom-file-input:focus ~.custom-file-label { + border-color: #90aece; + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.custom-file-input:disabled ~.custom-file-label { + background-color: #eee +} + +.custom-file-input:lang(en) ~.custom-file-label::after { + content: "Browse" +} + +.custom-file-input ~.custom-file-label[data-browse]::after { + content: attr(data-browse) +} + +.custom-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + height: calc(1.5em + .75rem + 2px); + padding: .375rem .75rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: .25rem +} + +.custom-file-label::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + z-index: 3; + display: block; + height: calc(1.5em + .75rem); + padding: .375rem .75rem; + line-height: 1.5; + color: #495057; + content: "Browse"; + background-color: #eee; + border-left: inherit; + border-radius: 0 .25rem .25rem 0 +} + +.custom-range { + width: 100%; + height: calc(1rem + .4rem); + padding: 0; + background-color: transparent; + appearance: none +} + +.custom-range:focus { + outline: 0 +} + +.custom-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.custom-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.custom-range:focus::-ms-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.custom-range::-moz-focus-outer { + border: 0 +} + +.custom-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -.25rem; + background-color: #446e9b; + border: 0; + border-radius: 1rem; + transition: background-color .15s ease-in-out, border-color .15s + ease-in-out, box-shadow .15s ease-in-out; + appearance: none +} + +@media ( prefers-reduced-motion :reduce) { + .custom-range::-webkit-slider-thumb { + transition: none + } +} + +.custom-range::-webkit-slider-thumb:active { + background-color: #b4c8de +} + +.custom-range::-webkit-slider-runnable-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.custom-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #446e9b; + border: 0; + border-radius: 1rem; + transition: background-color .15s ease-in-out, border-color .15s + ease-in-out, box-shadow .15s ease-in-out; + appearance: none +} + +@media ( prefers-reduced-motion :reduce) { + .custom-range::-moz-range-thumb { + transition: none + } +} + +.custom-range::-moz-range-thumb:active { + background-color: #b4c8de +} + +.custom-range::-moz-range-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.custom-range::-ms-thumb { + width: 1rem; + height: 1rem; + margin-top: 0; + margin-right: .2rem; + margin-left: .2rem; + background-color: #446e9b; + border: 0; + border-radius: 1rem; + transition: background-color .15s ease-in-out, border-color .15s + ease-in-out, box-shadow .15s ease-in-out; + appearance: none +} + +@media ( prefers-reduced-motion :reduce) { + .custom-range::-ms-thumb { + transition: none + } +} + +.custom-range::-ms-thumb:active { + background-color: #b4c8de +} + +.custom-range::-ms-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: transparent; + border-color: transparent; + border-width: .5rem +} + +.custom-range::-ms-fill-lower { + background-color: #dee2e6; + border-radius: 1rem +} + +.custom-range::-ms-fill-upper { + margin-right: 15px; + background-color: #dee2e6; + border-radius: 1rem +} + +.custom-range:disabled::-webkit-slider-thumb { + background-color: #999 +} + +.custom-range:disabled::-webkit-slider-runnable-track { + cursor: default +} + +.custom-range:disabled::-moz-range-thumb { + background-color: #999 +} + +.custom-range:disabled::-moz-range-track { + cursor: default +} + +.custom-range:disabled::-ms-thumb { + background-color: #999 +} + +.custom-control-label::before, .custom-file-label, .custom-select { + transition: background-color .15s ease-in-out, border-color .15s + ease-in-out, box-shadow .15s ease-in-out +} + +@media ( prefers-reduced-motion :reduce) { + .custom-control-label::before, .custom-file-label, .custom-select { + transition: none + } +} + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.nav-link { + display: block; + padding: .5rem 1rem +} + +.nav-link:focus, .nav-link:hover { + text-decoration: none +} + +.nav-link.disabled { + color: #777; + pointer-events: none; + cursor: default +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6 +} + +.nav-tabs .nav-item { + margin-bottom: -1px +} + +.nav-tabs .nav-link { + border: 1px solid transparent; + border-top-left-radius: .25rem; + border-top-right-radius: .25rem +} + +.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { + border-color: #eee #eee #dee2e6 +} + +.nav-tabs .nav-link.disabled { + color: #777; + background-color: transparent; + border-color: transparent +} + +.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav-pills .nav-link { + border-radius: .25rem +} + +.nav-pills .nav-link.active, .nav-pills .show>.nav-link { + color: #fff; + background-color: #446e9b +} + +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center +} + +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center +} + +.tab-content>.tab-pane { + display: none +} + +.tab-content>.active { + display: block +} + +.navbar { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: .5rem 1rem +} + +.navbar>.container, .navbar>.container-fluid { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between +} + +.navbar-brand { + display: inline-block; + padding-top: .3125rem; + padding-bottom: .3125rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; + white-space: nowrap +} + +.navbar-brand:focus, .navbar-brand:hover { + text-decoration: none +} + +.navbar-nav { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0 +} + +.navbar-nav .dropdown-menu { + position: static; + float: none +} + +.navbar-text { + display: inline-block; + padding-top: .5rem; + padding-bottom: .5rem +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center +} + +.navbar-toggler { + padding: .25rem .75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: .25rem +} + +.navbar-toggler:focus, .navbar-toggler:hover { + text-decoration: none +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ""; + background: no-repeat center center; + background-size: 100% 100% +} + +@media ( max-width :575.98px) { + .navbar-expand-sm>.container, .navbar-expand-sm>.container-fluid { + padding-right: 0; + padding-left: 0 + } +} + +@media ( min-width :576px) { + .navbar-expand-sm { + flex-flow: row nowrap; + justify-content: flex-start + } + .navbar-expand-sm .navbar-nav { + flex-direction: row + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + .navbar-expand-sm>.container, .navbar-expand-sm>.container-fluid { + flex-wrap: nowrap + } + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto + } + .navbar-expand-sm .navbar-toggler { + display: none + } +} + +@media ( max-width :767.98px) { + .navbar-expand-md>.container, .navbar-expand-md>.container-fluid { + padding-right: 0; + padding-left: 0 + } +} + +@media ( min-width :768px) { + .navbar-expand-md { + flex-flow: row nowrap; + justify-content: flex-start + } + .navbar-expand-md .navbar-nav { + flex-direction: row + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + .navbar-expand-md>.container, .navbar-expand-md>.container-fluid { + flex-wrap: nowrap + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto + } + .navbar-expand-md .navbar-toggler { + display: none + } +} + +@media ( max-width :991.98px) { + .navbar-expand-lg>.container, .navbar-expand-lg>.container-fluid { + padding-right: 0; + padding-left: 0 + } +} + +@media ( min-width :992px) { + .navbar-expand-lg { + flex-flow: row nowrap; + justify-content: flex-start + } + .navbar-expand-lg .navbar-nav { + flex-direction: row + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + .navbar-expand-lg>.container, .navbar-expand-lg>.container-fluid { + flex-wrap: nowrap + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto + } + .navbar-expand-lg .navbar-toggler { + display: none + } +} + +@media ( max-width :1199.98px) { + .navbar-expand-xl>.container, .navbar-expand-xl>.container-fluid { + padding-right: 0; + padding-left: 0 + } +} + +@media ( min-width :1200px) { + .navbar-expand-xl { + flex-flow: row nowrap; + justify-content: flex-start + } + .navbar-expand-xl .navbar-nav { + flex-direction: row + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem + } + .navbar-expand-xl>.container, .navbar-expand-xl>.container-fluid { + flex-wrap: nowrap + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + .navbar-expand-xl .navbar-toggler { + display: none + } +} + +.navbar-expand { + flex-flow: row nowrap; + justify-content: flex-start +} + +.navbar-expand>.container, .navbar-expand>.container-fluid { + padding-right: 0; + padding-left: 0 +} + +.navbar-expand .navbar-nav { + flex-direction: row +} + +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute +} + +.navbar-expand .navbar-nav .nav-link { + padding-right: .5rem; + padding-left: .5rem +} + +.navbar-expand>.container, .navbar-expand>.container-fluid { + flex-wrap: nowrap +} + +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto +} + +.navbar-expand .navbar-toggler { + display: none +} + +.navbar-light .navbar-brand { + color: #3399f3 +} + +.navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover { + color: #3399f3 +} + +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, .4) +} + +.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover + { + color: #3399f3 +} + +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, .3) +} + +.navbar-light .navbar-nav .active>.nav-link, .navbar-light .navbar-nav .nav-link.active, + .navbar-light .navbar-nav .nav-link.show, .navbar-light .navbar-nav .show>.nav-link + { + color: #3399f3 +} + +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, .4); + border-color: rgba(0, 0, 0, .1) +} + +.navbar-light .navbar-toggler-icon { + background-image: + url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.4)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.navbar-light .navbar-text { + color: rgba(0, 0, 0, .4) +} + +.navbar-light .navbar-text a { + color: #3399f3 +} + +.navbar-light .navbar-text a:focus, .navbar-light .navbar-text a:hover { + color: #3399f3 +} + +.navbar-dark .navbar-brand { + color: #fff +} + +.navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover { + color: #fff +} + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, .75) +} + +.navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover + { + color: #fff +} + +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, .25) +} + +.navbar-dark .navbar-nav .active>.nav-link, .navbar-dark .navbar-nav .nav-link.active, + .navbar-dark .navbar-nav .nav-link.show, .navbar-dark .navbar-nav .show>.nav-link + { + color: #fff +} + +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, .75); + border-color: rgba(255, 255, 255, .1) +} + +.navbar-dark .navbar-toggler-icon { + background-image: + url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.75)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, .75) +} + +.navbar-dark .navbar-text a { + color: #fff +} + +.navbar-dark .navbar-text a:focus, .navbar-dark .navbar-text a:hover { + color: #fff +} + +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, .125); + border-radius: .25rem +} + +.card>hr { + margin-right: 0; + margin-left: 0 +} + +.card>.list-group:first-child .list-group-item:first-child { + border-top-left-radius: .25rem; + border-top-right-radius: .25rem +} + +.card>.list-group:last-child .list-group-item:last-child { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.card-body { + flex: 1 1 auto; + padding: 1.25rem +} + +.card-title { + margin-bottom: .75rem +} + +.card-subtitle { + margin-top: -.375rem; + margin-bottom: 0 +} + +.card-text:last-child { + margin-bottom: 0 +} + +.card-link:hover { + text-decoration: none +} + +.card-link+.card-link { + margin-left: 1.25rem +} + +.card-header { + padding: .75rem 1.25rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, .03); + border-bottom: 1px solid rgba(0, 0, 0, .125) +} + +.card-header:first-child { + border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0 +} + +.card-header+.list-group .list-group-item:first-child { + border-top: 0 +} + +.card-footer { + padding: .75rem 1.25rem; + background-color: rgba(0, 0, 0, .03); + border-top: 1px solid rgba(0, 0, 0, .125) +} + +.card-footer:last-child { + border-radius: 0 0 calc(.25rem - 1px) calc(.25rem - 1px) +} + +.card-header-tabs { + margin-right: -.625rem; + margin-bottom: -.75rem; + margin-left: -.625rem; + border-bottom: 0 +} + +.card-header-pills { + margin-right: -.625rem; + margin-left: -.625rem +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem +} + +.card-img { + width: 100%; + border-radius: calc(.25rem - 1px) +} + +.card-img-top { + width: 100%; + border-top-left-radius: calc(.25rem - 1px); + border-top-right-radius: calc(.25rem - 1px) +} + +.card-img-bottom { + width: 100%; + border-bottom-right-radius: calc(.25rem - 1px); + border-bottom-left-radius: calc(.25rem - 1px) +} + +.card-deck { + display: flex; + flex-direction: column +} + +.card-deck .card { + margin-bottom: 15px +} + +@media ( min-width :576px) { + .card-deck { + flex-flow: row wrap; + margin-right: -15px; + margin-left: -15px + } + .card-deck .card { + display: flex; + flex: 1 0 0%; + flex-direction: column; + margin-right: 15px; + margin-bottom: 0; + margin-left: 15px + } +} + +.card-group { + display: flex; + flex-direction: column +} + +.card-group>.card { + margin-bottom: 15px +} + +@media ( min-width :576px) { + .card-group { + flex-flow: row wrap + } + .card-group>.card { + flex: 1 0 0%; + margin-bottom: 0 + } + .card-group>.card+.card { + margin-left: 0; + border-left: 0 + } + .card-group>.card:not (:last-child ){ + border-top-right-radius: 0; + border-bottom-right-radius: 0 + } + .card-group>.card:not (:last-child ) .card-header, .card-group>.card:not + (:last-child ) .card-img-top { + border-top-right-radius: 0 + } + .card-group>.card:not (:last-child ) .card-footer, .card-group>.card:not + (:last-child ) .card-img-bottom { + border-bottom-right-radius: 0 + } + .card-group>.card:not (:first-child ){ + border-top-left-radius: 0; + border-bottom-left-radius: 0 + } + .card-group>.card:not (:first-child ) .card-header, .card-group>.card:not + (:first-child ) .card-img-top { + border-top-left-radius: 0 + } + .card-group>.card:not (:first-child ) .card-footer, .card-group>.card:not + (:first-child ) .card-img-bottom { + border-bottom-left-radius: 0 + } +} + +.card-columns .card { + margin-bottom: .75rem +} + +@media ( min-width :576px) { + .card-columns { + column-count: 3; + column-gap: 1.25rem; + orphans: 1; + widows: 1 + } + .card-columns .card { + display: inline-block; + width: 100% + } +} + +.accordion>.card { + overflow: hidden +} + +.accordion>.card:not (:first-of-type ) .card-header:first-child { + border-radius: 0 +} + +.accordion>.card:not (:first-of-type ):not (:last-of-type ){ + border-bottom: 0; + border-radius: 0 +} + +.accordion>.card:first-of-type { + border-bottom: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.accordion>.card:last-of-type { + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.accordion>.card .card-header { + margin-bottom: -1px +} + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: .75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #eee; + border-radius: .25rem +} + +.breadcrumb-item+.breadcrumb-item { + padding-left: .5rem +} + +.breadcrumb-item+.breadcrumb-item::before { + display: inline-block; + padding-right: .5rem; + color: #777; + content: "/" +} + +.breadcrumb-item+.breadcrumb-item:hover::before { + text-decoration: underline +} + +.breadcrumb-item+.breadcrumb-item:hover::before { + text-decoration: none +} + +.breadcrumb-item.active { + color: #777 +} + +.pagination { + display: flex; + padding-left: 0; + list-style: none; + border-radius: .25rem +} + +.page-link { + position: relative; + display: block; + padding: .5rem .75rem; + margin-left: -1px; + line-height: 1.25; + color: #3399f3; + background-color: #fff; + border: 1px solid #dee2e6 +} + +.page-link:hover { + z-index: 2; + color: #0c73cd; + text-decoration: none; + background-color: #eee; + border-color: #dee2e6 +} + +.page-link:focus { + z-index: 2; + outline: 0; + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .25) +} + +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.page-item:last-child .page-link { + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem +} + +.page-item.active .page-link { + z-index: 1; + color: #fff; + background-color: #446e9b; + border-color: #446e9b +} + +.page-item.disabled .page-link { + color: #777; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6 +} + +.pagination-lg .page-link { + padding: .75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.5 +} + +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: .3rem; + border-bottom-left-radius: .3rem +} + +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: .3rem; + border-bottom-right-radius: .3rem +} + +.pagination-sm .page-link { + padding: .25rem .5rem; + font-size: .875rem; + line-height: 1.5 +} + +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: .2rem; + border-bottom-left-radius: .2rem +} + +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: .2rem; + border-bottom-right-radius: .2rem +} + +.badge { + display: inline-block; + padding: .25em .4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25rem; + transition: color .15s ease-in-out, background-color .15s ease-in-out, + border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media ( prefers-reduced-motion :reduce) { + .badge { + transition: none + } +} + +a.badge:focus, a.badge:hover { + text-decoration: none +} + +.badge:empty { + display: none +} + +.btn .badge { + position: relative; + top: -1px +} + +.badge-pill { + padding-right: .6em; + padding-left: .6em; + border-radius: 10rem +} + +.badge-primary { + color: #fff; + background-color: #446e9b +} + +a.badge-primary:focus, a.badge-primary:hover { + color: #fff; + background-color: #345578 +} + +a.badge-primary.focus, a.badge-primary:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(68, 110, 155, .5) +} + +.badge-secondary { + color: #fff; + background-color: #999 +} + +a.badge-secondary:focus, a.badge-secondary:hover { + color: #fff; + background-color: gray +} + +a.badge-secondary.focus, a.badge-secondary:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(153, 153, 153, .5) +} + +.badge-success { + color: #fff; + background-color: #3cb521 +} + +a.badge-success:focus, a.badge-success:hover { + color: #fff; + background-color: #2e8a19 +} + +a.badge-success.focus, a.badge-success:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(60, 181, 33, .5) +} + +.badge-info { + color: #fff; + background-color: #3399f3 +} + +a.badge-info:focus, a.badge-info:hover { + color: #fff; + background-color: #0e80e6 +} + +a.badge-info.focus, a.badge-info:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(51, 153, 243, .5) +} + +.badge-warning { + color: #fff; + background-color: #d47500 +} + +a.badge-warning:focus, a.badge-warning:hover { + color: #fff; + background-color: #a15900 +} + +a.badge-warning.focus, a.badge-warning:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(212, 117, 0, .5) +} + +.badge-danger { + color: #fff; + background-color: #cd0200 +} + +a.badge-danger:focus, a.badge-danger:hover { + color: #fff; + background-color: #9a0200 +} + +a.badge-danger.focus, a.badge-danger:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(205, 2, 0, .5) +} + +.badge-light { + color: #2d2d2d; + background-color: #eee +} + +a.badge-light:focus, a.badge-light:hover { + color: #2d2d2d; + background-color: #d5d5d5 +} + +a.badge-light.focus, a.badge-light:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(238, 238, 238, .5) +} + +.badge-dark { + color: #fff; + background-color: #333 +} + +a.badge-dark:focus, a.badge-dark:hover { + color: #fff; + background-color: #1a1a1a +} + +a.badge-dark.focus, a.badge-dark:focus { + outline: 0; + box-shadow: 0 0 0 .2rem rgba(51, 51, 51, .5) +} + +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #eee; + border-radius: .3rem +} + +@media ( min-width :576px) { + .jumbotron { + padding: 4rem 2rem + } +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + border-radius: 0 +} + +.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: #233951; + background-color: #dae2eb; + border-color: #cbd6e3 +} + +.alert-primary hr { + border-top-color: #bac9da +} + +.alert-primary .alert-link { + color: #14202d +} + +.alert-secondary { + color: #505050; + background-color: #ebebeb; + border-color: #e2e2e2 +} + +.alert-secondary hr { + border-top-color: #d5d5d5 +} + +.alert-secondary .alert-link { + color: #373737 +} + +.alert-success { + color: #1f5e11; + background-color: #d8f0d3; + border-color: #c8eac1 +} + +.alert-success hr { + border-top-color: #b7e4ae +} + +.alert-success .alert-link { + color: #113309 +} + +.alert-info { + color: #1b507e; + background-color: #d6ebfd; + border-color: #c6e2fc +} + +.alert-info hr { + border-top-color: #aed6fb +} + +.alert-info .alert-link { + color: #123554 +} + +.alert-warning { + color: #6e3d00; + background-color: #f6e3cc; + border-color: #f3d8b8 +} + +.alert-warning hr { + border-top-color: #efcca2 +} + +.alert-warning .alert-link { + color: #3b2100 +} + +.alert-danger { + color: #6b0100; + background-color: #f5cccc; + border-color: #f1b8b8 +} + +.alert-danger hr { + border-top-color: #eda3a3 +} + +.alert-danger .alert-link { + color: #380100 +} + +.alert-light { + color: #7c7c7c; + background-color: #fcfcfc; + border-color: #fafafa +} + +.alert-light hr { + border-top-color: #ededed +} + +.alert-light .alert-link { + color: #636363 +} + +.alert-dark { + color: #1b1b1b; + background-color: #d6d6d6; + border-color: #c6c6c6 +} + +.alert-dark hr { + border-top-color: #b9b9b9 +} + +.alert-dark .alert-link { + color: #020202 +} + +@ +keyframes progress-bar-stripes { + from {background-position: 1rem 0 +} + +to { + background-position: 0 0 +} + +} +.progress { + display: flex; + height: 1rem; + overflow: hidden; + font-size: .75rem; + background-color: #eee; + border-radius: .25rem +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: #446e9b; + transition: width .6s ease +} + +@media ( prefers-reduced-motion :reduce) { + .progress-bar { + transition: none + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, + transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, + rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem +} + +.progress-bar-animated { + animation: progress-bar-stripes 1s linear infinite +} + +@media ( prefers-reduced-motion :reduce) { + .progress-bar-animated { + animation: none + } +} + +.media { + display: flex; + align-items: flex-start +} + +.media-body { + flex: 1 +} + +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0 +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit +} + +.list-group-item-action:focus, .list-group-item-action:hover { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa +} + +.list-group-item-action:active { + color: #777; + background-color: #eee +} + +.list-group-item { + position: relative; + display: block; + padding: .75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, .125) +} + +.list-group-item:first-child { + border-top-left-radius: .25rem; + border-top-right-radius: .25rem +} + +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem +} + +.list-group-item.disabled, .list-group-item:disabled { + color: #777; + pointer-events: none; + background-color: #fff +} + +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #446e9b; + border-color: #446e9b +} + +.list-group-horizontal { + flex-direction: row +} + +.list-group-horizontal .list-group-item { + margin-right: -1px; + margin-bottom: 0 +} + +.list-group-horizontal .list-group-item:first-child { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 +} + +.list-group-horizontal .list-group-item:last-child { + margin-right: 0; + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; + border-bottom-left-radius: 0 +} + +@media ( min-width :576px) { + .list-group-horizontal-sm { + flex-direction: row + } + .list-group-horizontal-sm .list-group-item { + margin-right: -1px; + margin-bottom: 0 + } + .list-group-horizontal-sm .list-group-item:first-child { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + .list-group-horizontal-sm .list-group-item:last-child { + margin-right: 0; + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; + border-bottom-left-radius: 0 + } +} + +@media ( min-width :768px) { + .list-group-horizontal-md { + flex-direction: row + } + .list-group-horizontal-md .list-group-item { + margin-right: -1px; + margin-bottom: 0 + } + .list-group-horizontal-md .list-group-item:first-child { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + .list-group-horizontal-md .list-group-item:last-child { + margin-right: 0; + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; + border-bottom-left-radius: 0 + } +} + +@media ( min-width :992px) { + .list-group-horizontal-lg { + flex-direction: row + } + .list-group-horizontal-lg .list-group-item { + margin-right: -1px; + margin-bottom: 0 + } + .list-group-horizontal-lg .list-group-item:first-child { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + .list-group-horizontal-lg .list-group-item:last-child { + margin-right: 0; + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; + border-bottom-left-radius: 0 + } +} + +@media ( min-width :1200px) { + .list-group-horizontal-xl { + flex-direction: row + } + .list-group-horizontal-xl .list-group-item { + margin-right: -1px; + margin-bottom: 0 + } + .list-group-horizontal-xl .list-group-item:first-child { + border-top-left-radius: .25rem; + border-bottom-left-radius: .25rem; + border-top-right-radius: 0 + } + .list-group-horizontal-xl .list-group-item:last-child { + margin-right: 0; + border-top-right-radius: .25rem; + border-bottom-right-radius: .25rem; + border-bottom-left-radius: 0 + } +} + +.list-group-flush .list-group-item { + border-right: 0; + border-left: 0; + border-radius: 0 +} + +.list-group-flush .list-group-item:last-child { + margin-bottom: -1px +} + +.list-group-flush:first-child .list-group-item:first-child { + border-top: 0 +} + +.list-group-flush:last-child .list-group-item:last-child { + margin-bottom: 0; + border-bottom: 0 +} + +.list-group-item-primary { + color: #233951; + background-color: #cbd6e3 +} + +.list-group-item-primary.list-group-item-action:focus, + .list-group-item-primary.list-group-item-action:hover { + color: #233951; + background-color: #bac9da +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #233951; + border-color: #233951 +} + +.list-group-item-secondary { + color: #505050; + background-color: #e2e2e2 +} + +.list-group-item-secondary.list-group-item-action:focus, + .list-group-item-secondary.list-group-item-action:hover { + color: #505050; + background-color: #d5d5d5 +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #505050; + border-color: #505050 +} + +.list-group-item-success { + color: #1f5e11; + background-color: #c8eac1 +} + +.list-group-item-success.list-group-item-action:focus, + .list-group-item-success.list-group-item-action:hover { + color: #1f5e11; + background-color: #b7e4ae +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #1f5e11; + border-color: #1f5e11 +} + +.list-group-item-info { + color: #1b507e; + background-color: #c6e2fc +} + +.list-group-item-info.list-group-item-action:focus, + .list-group-item-info.list-group-item-action:hover { + color: #1b507e; + background-color: #aed6fb +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #1b507e; + border-color: #1b507e +} + +.list-group-item-warning { + color: #6e3d00; + background-color: #f3d8b8 +} + +.list-group-item-warning.list-group-item-action:focus, + .list-group-item-warning.list-group-item-action:hover { + color: #6e3d00; + background-color: #efcca2 +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #6e3d00; + border-color: #6e3d00 +} + +.list-group-item-danger { + color: #6b0100; + background-color: #f1b8b8 +} + +.list-group-item-danger.list-group-item-action:focus, + .list-group-item-danger.list-group-item-action:hover { + color: #6b0100; + background-color: #eda3a3 +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #6b0100; + border-color: #6b0100 +} + +.list-group-item-light { + color: #7c7c7c; + background-color: #fafafa +} + +.list-group-item-light.list-group-item-action:focus, + .list-group-item-light.list-group-item-action:hover { + color: #7c7c7c; + background-color: #ededed +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #7c7c7c; + border-color: #7c7c7c +} + +.list-group-item-dark { + color: #1b1b1b; + background-color: #c6c6c6 +} + +.list-group-item-dark.list-group-item-action:focus, + .list-group-item-dark.list-group-item-action:hover { + color: #1b1b1b; + background-color: #b9b9b9 +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1b1b1b; + border-color: #1b1b1b +} + +.close { + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .5 +} + +.close:hover { + color: #000; + text-decoration: none +} + +.close:not (:disabled ):not (.disabled ):focus, .close:not (:disabled ):not + (.disabled ):hover { + opacity: .75 +} + +button.close { + padding: 0; + background-color: transparent; + border: 0; + appearance: none +} + +a.close.disabled { + pointer-events: none +} + +.toast { + max-width: 350px; + overflow: hidden; + font-size: .875rem; + background-color: rgba(255, 255, 255, .85); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .1); + box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .1); + backdrop-filter: blur(10px); + opacity: 0; + border-radius: .25rem +} + +.toast:not (:last-child ){ + margin-bottom: .75rem +} + +.toast.showing { + opacity: 1 +} + +.toast.show { + display: block; + opacity: 1 +} + +.toast.hide { + display: none +} + +.toast-header { + display: flex; + align-items: center; + padding: .25rem .75rem; + color: #777; + background-color: rgba(255, 255, 255, .85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, .05) +} + +.toast-body { + padding: .75rem +} + +.modal-open { + overflow: hidden +} + +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto +} + +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1050; + display: none; + width: 100%; + height: 100%; + overflow: hidden; + outline: 0 +} + +.modal-dialog { + position: relative; + width: auto; + margin: .5rem; + pointer-events: none +} + +.modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translate(0, -50px) +} + +@media ( prefers-reduced-motion :reduce) { + .modal.fade .modal-dialog { + transition: none + } +} + +.modal.show .modal-dialog { + transform: none +} + +.modal-dialog-scrollable { + display: flex; + max-height: calc(100% - 1rem) +} + +.modal-dialog-scrollable .modal-content { + max-height: calc(100vh - 1rem); + overflow: hidden +} + +.modal-dialog-scrollable .modal-footer, .modal-dialog-scrollable .modal-header + { + flex-shrink: 0 +} + +.modal-dialog-scrollable .modal-body { + overflow-y: auto +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - 1rem) +} + +.modal-dialog-centered::before { + display: block; + height: calc(100vh - 1rem); + content: "" +} + +.modal-dialog-centered.modal-dialog-scrollable { + flex-direction: column; + justify-content: center; + height: 100% +} + +.modal-dialog-centered.modal-dialog-scrollable .modal-content { + max-height: none +} + +.modal-dialog-centered.modal-dialog-scrollable::before { + content: none +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: .3rem; + outline: 0 +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000 +} + +.modal-backdrop.fade { + opacity: 0 +} + +.modal-backdrop.show { + opacity: .5 +} + +.modal-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + padding: 1rem 1rem; + border-bottom: 1px solid #dee2e6; + border-top-left-radius: .3rem; + border-top-right-radius: .3rem +} + +.modal-header .close { + padding: 1rem 1rem; + margin: -1rem -1rem -1rem auto +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5 +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 1rem +} + +.modal-footer { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 1rem; + border-top: 1px solid #dee2e6; + border-bottom-right-radius: .3rem; + border-bottom-left-radius: .3rem +} + +.modal-footer>:not (:first-child ){ + margin-left: .25rem +} + +.modal-footer>:not (:last-child ){ + margin-right: .25rem +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll +} + +@media ( min-width :576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto + } + .modal-dialog-scrollable { + max-height: calc(100% - 3.5rem) + } + .modal-dialog-scrollable .modal-content { + max-height: calc(100vh - 3.5rem) + } + .modal-dialog-centered { + min-height: calc(100% - 3.5rem) + } + .modal-dialog-centered::before { + height: calc(100vh - 3.5rem) + } + .modal-sm { + max-width: 300px + } +} + +@media ( min-width :992px) { + .modal-lg, .modal-xl { + max-width: 800px + } +} + +@media ( min-width :1200px) { + .modal-xl { + max-width: 1140px + } +} + +.tooltip { + position: absolute; + z-index: 1070; + display: block; + margin: 0; + font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", + Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: .875rem; + word-wrap: break-word; + opacity: 0 +} + +.tooltip.show { + opacity: .9 +} + +.tooltip .arrow { + position: absolute; + display: block; + width: .8rem; + height: .4rem +} + +.tooltip .arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid +} + +.bs-tooltip-auto[x-placement^=top], .bs-tooltip-top { + padding: .4rem 0 +} + +.bs-tooltip-auto[x-placement^=top] .arrow, .bs-tooltip-top .arrow { + bottom: 0 +} + +.bs-tooltip-auto[x-placement^=top] .arrow::before, .bs-tooltip-top .arrow::before + { + top: 0; + border-width: .4rem .4rem 0; + border-top-color: #000 +} + +.bs-tooltip-auto[x-placement^=right], .bs-tooltip-right { + padding: 0 .4rem +} + +.bs-tooltip-auto[x-placement^=right] .arrow, .bs-tooltip-right .arrow { + left: 0; + width: .4rem; + height: .8rem +} + +.bs-tooltip-auto[x-placement^=right] .arrow::before, .bs-tooltip-right .arrow::before + { + right: 0; + border-width: .4rem .4rem .4rem 0; + border-right-color: #000 +} + +.bs-tooltip-auto[x-placement^=bottom], .bs-tooltip-bottom { + padding: .4rem 0 +} + +.bs-tooltip-auto[x-placement^=bottom] .arrow, .bs-tooltip-bottom .arrow + { + top: 0 +} + +.bs-tooltip-auto[x-placement^=bottom] .arrow::before, .bs-tooltip-bottom .arrow::before + { + bottom: 0; + border-width: 0 .4rem .4rem; + border-bottom-color: #000 +} + +.bs-tooltip-auto[x-placement^=left], .bs-tooltip-left { + padding: 0 .4rem +} + +.bs-tooltip-auto[x-placement^=left] .arrow, .bs-tooltip-left .arrow { + right: 0; + width: .4rem; + height: .8rem +} + +.bs-tooltip-auto[x-placement^=left] .arrow::before, .bs-tooltip-left .arrow::before + { + left: 0; + border-width: .4rem 0 .4rem .4rem; + border-left-color: #000 +} + +.tooltip-inner { + max-width: 200px; + padding: .25rem .5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: .25rem +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", + Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: .875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: .3rem +} + +.popover .arrow { + position: absolute; + display: block; + width: 1rem; + height: .5rem; + margin: 0 .3rem +} + +.popover .arrow::after, .popover .arrow::before { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid +} + +.bs-popover-auto[x-placement^=top], .bs-popover-top { + margin-bottom: .5rem +} + +.bs-popover-auto[x-placement^=top]>.arrow, .bs-popover-top>.arrow { + bottom: calc(( .5rem + 1px)* -1) +} + +.bs-popover-auto[x-placement^=top]>.arrow::before, .bs-popover-top>.arrow::before + { + bottom: 0; + border-width: .5rem .5rem 0; + border-top-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[x-placement^=top]>.arrow::after, .bs-popover-top>.arrow::after + { + bottom: 1px; + border-width: .5rem .5rem 0; + border-top-color: #fff +} + +.bs-popover-auto[x-placement^=right], .bs-popover-right { + margin-left: .5rem +} + +.bs-popover-auto[x-placement^=right]>.arrow, .bs-popover-right>.arrow { + left: calc(( .5rem + 1px)* -1); + width: .5rem; + height: 1rem; + margin: .3rem 0 +} + +.bs-popover-auto[x-placement^=right]>.arrow::before, .bs-popover-right>.arrow::before + { + left: 0; + border-width: .5rem .5rem .5rem 0; + border-right-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[x-placement^=right]>.arrow::after, .bs-popover-right>.arrow::after + { + left: 1px; + border-width: .5rem .5rem .5rem 0; + border-right-color: #fff +} + +.bs-popover-auto[x-placement^=bottom], .bs-popover-bottom { + margin-top: .5rem +} + +.bs-popover-auto[x-placement^=bottom]>.arrow, .bs-popover-bottom>.arrow + { + top: calc(( .5rem + 1px)* -1) +} + +.bs-popover-auto[x-placement^=bottom]>.arrow::before, .bs-popover-bottom>.arrow::before + { + top: 0; + border-width: 0 .5rem .5rem .5rem; + border-bottom-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[x-placement^=bottom]>.arrow::after, .bs-popover-bottom>.arrow::after + { + top: 1px; + border-width: 0 .5rem .5rem .5rem; + border-bottom-color: #fff +} + +.bs-popover-auto[x-placement^=bottom] .popover-header::before, + .bs-popover-bottom .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -.5rem; + content: ""; + border-bottom: 1px solid #f7f7f7 +} + +.bs-popover-auto[x-placement^=left], .bs-popover-left { + margin-right: .5rem +} + +.bs-popover-auto[x-placement^=left]>.arrow, .bs-popover-left>.arrow { + right: calc(( .5rem + 1px)* -1); + width: .5rem; + height: 1rem; + margin: .3rem 0 +} + +.bs-popover-auto[x-placement^=left]>.arrow::before, .bs-popover-left>.arrow::before + { + right: 0; + border-width: .5rem 0 .5rem .5rem; + border-left-color: rgba(0, 0, 0, .25) +} + +.bs-popover-auto[x-placement^=left]>.arrow::after, .bs-popover-left>.arrow::after + { + right: 1px; + border-width: .5rem 0 .5rem .5rem; + border-left-color: #fff +} + +.popover-header { + padding: .5rem .75rem; + margin-bottom: 0; + font-size: 1rem; + color: #2d2d2d; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-top-left-radius: calc(.3rem - 1px); + border-top-right-radius: calc(.3rem - 1px) +} + +.popover-header:empty { + display: none +} + +.popover-body { + padding: .5rem .75rem; + color: #777 +} + +.carousel { + position: relative +} + +.carousel.pointer-event { + touch-action: pan-y +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden +} + +.carousel-inner::after { + display: block; + clear: both; + content: "" +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + backface-visibility: hidden; + transition: transform .6s ease-in-out +} + +@media ( prefers-reduced-motion :reduce) { + .carousel-item { + transition: none + } +} + +.carousel-item-next, .carousel-item-prev, .carousel-item.active { + display: block +} + +.active.carousel-item-right, .carousel-item-next:not (.carousel-item-left + ){ + transform: translateX(100%) +} + +.active.carousel-item-left, .carousel-item-prev:not (.carousel-item-right + ){ + transform: translateX(-100%) +} + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none +} + +.carousel-fade .carousel-item-next.carousel-item-left, .carousel-fade .carousel-item-prev.carousel-item-right, + .carousel-fade .carousel-item.active { + z-index: 1; + opacity: 1 +} + +.carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right + { + z-index: 0; + opacity: 0; + transition: 0s .6s opacity +} + +@media ( prefers-reduced-motion :reduce) { + .carousel-fade .active.carousel-item-left, .carousel-fade .active.carousel-item-right + { + transition: none + } +} + +.carousel-control-next, .carousel-control-prev { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + color: #fff; + text-align: center; + opacity: .5; + transition: opacity .15s ease +} + +@media ( prefers-reduced-motion :reduce) { + .carousel-control-next, .carousel-control-prev { + transition: none + } +} + +.carousel-control-next:focus, .carousel-control-next:hover, + .carousel-control-prev:focus, .carousel-control-prev:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9 +} + +.carousel-control-prev { + left: 0 +} + +.carousel-control-next { + right: 0 +} + +.carousel-control-next-icon, .carousel-control-prev-icon { + display: inline-block; + width: 20px; + height: 20px; + background: no-repeat 50%/100% 100% +} + +.carousel-control-prev-icon { + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e") +} + +.carousel-control-next-icon { + background-image: + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e") +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 15; + display: flex; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none +} + +.carousel-indicators li { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: .5; + transition: opacity .6s ease +} + +@media ( prefers-reduced-motion :reduce) { + .carousel-indicators li { + transition: none + } +} + +.carousel-indicators .active { + opacity: 1 +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center +} + +@ +keyframes spinner-border { + to {transform: rotate(360deg) +} + +} +.spinner-border { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: text-bottom; + border: .25em solid currentColor; + border-right-color: transparent; + border-radius: 50%; + animation: spinner-border .75s linear infinite +} + +.spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: .2em +} + +@ +keyframes spinner-grow { 0%{ + transform: scale(0) +} + +50%{ +opacity +: +1 +} +} +.spinner-grow { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: text-bottom; + background-color: currentColor; + border-radius: 50%; + opacity: 0; + animation: spinner-grow .75s linear infinite +} + +.spinner-grow-sm { + width: 1rem; + height: 1rem +} + +.align-baseline { + vertical-align: baseline !important +} + +.align-top { + vertical-align: top !important +} + +.align-middle { + vertical-align: middle !important +} + +.align-bottom { + vertical-align: bottom !important +} + +.align-text-bottom { + vertical-align: text-bottom !important +} + +.align-text-top { + vertical-align: text-top !important +} + +.bg-primary { + background-color: #446e9b !important +} + +a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover + { + background-color: #345578 !important +} + +.bg-secondary { + background-color: #999 !important +} + +a.bg-secondary:focus, a.bg-secondary:hover, button.bg-secondary:focus, + button.bg-secondary:hover { + background-color: gray !important +} + +.bg-success { + background-color: #3cb521 !important +} + +a.bg-success:focus, a.bg-success:hover, button.bg-success:focus, button.bg-success:hover + { + background-color: #2e8a19 !important +} + +.bg-info { + background-color: #3399f3 !important +} + +a.bg-info:focus, a.bg-info:hover, button.bg-info:focus, button.bg-info:hover + { + background-color: #0e80e6 !important +} + +.bg-warning { + background-color: #d47500 !important +} + +a.bg-warning:focus, a.bg-warning:hover, button.bg-warning:focus, button.bg-warning:hover + { + background-color: #a15900 !important +} + +.bg-danger { + background-color: #cd0200 !important +} + +a.bg-danger:focus, a.bg-danger:hover, button.bg-danger:focus, button.bg-danger:hover + { + background-color: #9a0200 !important +} + +.bg-light { + background-color: #eee !important +} + +a.bg-light:focus, a.bg-light:hover, button.bg-light:focus, button.bg-light:hover + { + background-color: #d5d5d5 !important +} + +.bg-dark { + background-color: #333 !important +} + +a.bg-dark:focus, a.bg-dark:hover, button.bg-dark:focus, button.bg-dark:hover + { + background-color: #1a1a1a !important +} + +.bg-white { + background-color: #fff !important +} + +.bg-transparent { + background-color: transparent !important +} + +.border { + border: 1px solid #dee2e6 !important +} + +.border-top { + border-top: 1px solid #dee2e6 !important +} + +.border-right { + border-right: 1px solid #dee2e6 !important +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important +} + +.border-left { + border-left: 1px solid #dee2e6 !important +} + +.border-0 { + border: 0 !important +} + +.border-top-0 { + border-top: 0 !important +} + +.border-right-0 { + border-right: 0 !important +} + +.border-bottom-0 { + border-bottom: 0 !important +} + +.border-left-0 { + border-left: 0 !important +} + +.border-primary { + border-color: #446e9b !important +} + +.border-secondary { + border-color: #999 !important +} + +.border-success { + border-color: #3cb521 !important +} + +.border-info { + border-color: #3399f3 !important +} + +.border-warning { + border-color: #d47500 !important +} + +.border-danger { + border-color: #cd0200 !important +} + +.border-light { + border-color: #eee !important +} + +.border-dark { + border-color: #333 !important +} + +.border-white { + border-color: #fff !important +} + +.rounded-sm { + border-radius: .2rem !important +} + +.rounded { + border-radius: .25rem !important +} + +.rounded-top { + border-top-left-radius: .25rem !important; + border-top-right-radius: .25rem !important +} + +.rounded-right { + border-top-right-radius: .25rem !important; + border-bottom-right-radius: .25rem !important +} + +.rounded-bottom { + border-bottom-right-radius: .25rem !important; + border-bottom-left-radius: .25rem !important +} + +.rounded-left { + border-top-left-radius: .25rem !important; + border-bottom-left-radius: .25rem !important +} + +.rounded-lg { + border-radius: .3rem !important +} + +.rounded-circle { + border-radius: 50% !important +} + +.rounded-pill { + border-radius: 50rem !important +} + +.rounded-0 { + border-radius: 0 !important +} + +.clearfix::after { + display: block; + clear: both; + content: "" +} + +.d-none { + display: none !important +} + +.d-inline { + display: inline !important +} + +.d-inline-block { + display: inline-block !important +} + +.d-block { + display: block !important +} + +.d-table { + display: table !important +} + +.d-table-row { + display: table-row !important +} + +.d-table-cell { + display: table-cell !important +} + +.d-flex { + display: flex !important +} + +.d-inline-flex { + display: inline-flex !important +} + +@media ( min-width :576px) { + .d-sm-none { + display: none !important + } + .d-sm-inline { + display: inline !important + } + .d-sm-inline-block { + display: inline-block !important + } + .d-sm-block { + display: block !important + } + .d-sm-table { + display: table !important + } + .d-sm-table-row { + display: table-row !important + } + .d-sm-table-cell { + display: table-cell !important + } + .d-sm-flex { + display: flex !important + } + .d-sm-inline-flex { + display: inline-flex !important + } +} + +@media ( min-width :768px) { + .d-md-none { + display: none !important + } + .d-md-inline { + display: inline !important + } + .d-md-inline-block { + display: inline-block !important + } + .d-md-block { + display: block !important + } + .d-md-table { + display: table !important + } + .d-md-table-row { + display: table-row !important + } + .d-md-table-cell { + display: table-cell !important + } + .d-md-flex { + display: flex !important + } + .d-md-inline-flex { + display: inline-flex !important + } +} + +@media ( min-width :992px) { + .d-lg-none { + display: none !important + } + .d-lg-inline { + display: inline !important + } + .d-lg-inline-block { + display: inline-block !important + } + .d-lg-block { + display: block !important + } + .d-lg-table { + display: table !important + } + .d-lg-table-row { + display: table-row !important + } + .d-lg-table-cell { + display: table-cell !important + } + .d-lg-flex { + display: flex !important + } + .d-lg-inline-flex { + display: inline-flex !important + } +} + +@media ( min-width :1200px) { + .d-xl-none { + display: none !important + } + .d-xl-inline { + display: inline !important + } + .d-xl-inline-block { + display: inline-block !important + } + .d-xl-block { + display: block !important + } + .d-xl-table { + display: table !important + } + .d-xl-table-row { + display: table-row !important + } + .d-xl-table-cell { + display: table-cell !important + } + .d-xl-flex { + display: flex !important + } + .d-xl-inline-flex { + display: inline-flex !important + } +} + +@media print { + .d-print-none { + display: none !important + } + .d-print-inline { + display: inline !important + } + .d-print-inline-block { + display: inline-block !important + } + .d-print-block { + display: block !important + } + .d-print-table { + display: table !important + } + .d-print-table-row { + display: table-row !important + } + .d-print-table-cell { + display: table-cell !important + } + .d-print-flex { + display: flex !important + } + .d-print-inline-flex { + display: inline-flex !important + } +} + +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden +} + +.embed-responsive::before { + display: block; + content: "" +} + +.embed-responsive .embed-responsive-item, .embed-responsive embed, + .embed-responsive iframe, .embed-responsive object, .embed-responsive video + { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0 +} + +.embed-responsive-21by9::before { + padding-top: 42.85714% +} + +.embed-responsive-16by9::before { + padding-top: 56.25% +} + +.embed-responsive-4by3::before { + padding-top: 75% +} + +.embed-responsive-1by1::before { + padding-top: 100% +} + +.flex-row { + flex-direction: row !important +} + +.flex-column { + flex-direction: column !important +} + +.flex-row-reverse { + flex-direction: row-reverse !important +} + +.flex-column-reverse { + flex-direction: column-reverse !important +} + +.flex-wrap { + flex-wrap: wrap !important +} + +.flex-nowrap { + flex-wrap: nowrap !important +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important +} + +.flex-fill { + flex: 1 1 auto !important +} + +.flex-grow-0 { + flex-grow: 0 !important +} + +.flex-grow-1 { + flex-grow: 1 !important +} + +.flex-shrink-0 { + flex-shrink: 0 !important +} + +.flex-shrink-1 { + flex-shrink: 1 !important +} + +.justify-content-start { + justify-content: flex-start !important +} + +.justify-content-end { + justify-content: flex-end !important +} + +.justify-content-center { + justify-content: center !important +} + +.justify-content-between { + justify-content: space-between !important +} + +.justify-content-around { + justify-content: space-around !important +} + +.align-items-start { + align-items: flex-start !important +} + +.align-items-end { + align-items: flex-end !important +} + +.align-items-center { + align-items: center !important +} + +.align-items-baseline { + align-items: baseline !important +} + +.align-items-stretch { + align-items: stretch !important +} + +.align-content-start { + align-content: flex-start !important +} + +.align-content-end { + align-content: flex-end !important +} + +.align-content-center { + align-content: center !important +} + +.align-content-between { + align-content: space-between !important +} + +.align-content-around { + align-content: space-around !important +} + +.align-content-stretch { + align-content: stretch !important +} + +.align-self-auto { + align-self: auto !important +} + +.align-self-start { + align-self: flex-start !important +} + +.align-self-end { + align-self: flex-end !important +} + +.align-self-center { + align-self: center !important +} + +.align-self-baseline { + align-self: baseline !important +} + +.align-self-stretch { + align-self: stretch !important +} + +@media ( min-width :576px) { + .flex-sm-row { + flex-direction: row !important + } + .flex-sm-column { + flex-direction: column !important + } + .flex-sm-row-reverse { + flex-direction: row-reverse !important + } + .flex-sm-column-reverse { + flex-direction: column-reverse !important + } + .flex-sm-wrap { + flex-wrap: wrap !important + } + .flex-sm-nowrap { + flex-wrap: nowrap !important + } + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important + } + .flex-sm-fill { + flex: 1 1 auto !important + } + .flex-sm-grow-0 { + flex-grow: 0 !important + } + .flex-sm-grow-1 { + flex-grow: 1 !important + } + .flex-sm-shrink-0 { + flex-shrink: 0 !important + } + .flex-sm-shrink-1 { + flex-shrink: 1 !important + } + .justify-content-sm-start { + justify-content: flex-start !important + } + .justify-content-sm-end { + justify-content: flex-end !important + } + .justify-content-sm-center { + justify-content: center !important + } + .justify-content-sm-between { + justify-content: space-between !important + } + .justify-content-sm-around { + justify-content: space-around !important + } + .align-items-sm-start { + align-items: flex-start !important + } + .align-items-sm-end { + align-items: flex-end !important + } + .align-items-sm-center { + align-items: center !important + } + .align-items-sm-baseline { + align-items: baseline !important + } + .align-items-sm-stretch { + align-items: stretch !important + } + .align-content-sm-start { + align-content: flex-start !important + } + .align-content-sm-end { + align-content: flex-end !important + } + .align-content-sm-center { + align-content: center !important + } + .align-content-sm-between { + align-content: space-between !important + } + .align-content-sm-around { + align-content: space-around !important + } + .align-content-sm-stretch { + align-content: stretch !important + } + .align-self-sm-auto { + align-self: auto !important + } + .align-self-sm-start { + align-self: flex-start !important + } + .align-self-sm-end { + align-self: flex-end !important + } + .align-self-sm-center { + align-self: center !important + } + .align-self-sm-baseline { + align-self: baseline !important + } + .align-self-sm-stretch { + align-self: stretch !important + } +} + +@media ( min-width :768px) { + .flex-md-row { + flex-direction: row !important + } + .flex-md-column { + flex-direction: column !important + } + .flex-md-row-reverse { + flex-direction: row-reverse !important + } + .flex-md-column-reverse { + flex-direction: column-reverse !important + } + .flex-md-wrap { + flex-wrap: wrap !important + } + .flex-md-nowrap { + flex-wrap: nowrap !important + } + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important + } + .flex-md-fill { + flex: 1 1 auto !important + } + .flex-md-grow-0 { + flex-grow: 0 !important + } + .flex-md-grow-1 { + flex-grow: 1 !important + } + .flex-md-shrink-0 { + flex-shrink: 0 !important + } + .flex-md-shrink-1 { + flex-shrink: 1 !important + } + .justify-content-md-start { + justify-content: flex-start !important + } + .justify-content-md-end { + justify-content: flex-end !important + } + .justify-content-md-center { + justify-content: center !important + } + .justify-content-md-between { + justify-content: space-between !important + } + .justify-content-md-around { + justify-content: space-around !important + } + .align-items-md-start { + align-items: flex-start !important + } + .align-items-md-end { + align-items: flex-end !important + } + .align-items-md-center { + align-items: center !important + } + .align-items-md-baseline { + align-items: baseline !important + } + .align-items-md-stretch { + align-items: stretch !important + } + .align-content-md-start { + align-content: flex-start !important + } + .align-content-md-end { + align-content: flex-end !important + } + .align-content-md-center { + align-content: center !important + } + .align-content-md-between { + align-content: space-between !important + } + .align-content-md-around { + align-content: space-around !important + } + .align-content-md-stretch { + align-content: stretch !important + } + .align-self-md-auto { + align-self: auto !important + } + .align-self-md-start { + align-self: flex-start !important + } + .align-self-md-end { + align-self: flex-end !important + } + .align-self-md-center { + align-self: center !important + } + .align-self-md-baseline { + align-self: baseline !important + } + .align-self-md-stretch { + align-self: stretch !important + } +} + +@media ( min-width :992px) { + .flex-lg-row { + flex-direction: row !important + } + .flex-lg-column { + flex-direction: column !important + } + .flex-lg-row-reverse { + flex-direction: row-reverse !important + } + .flex-lg-column-reverse { + flex-direction: column-reverse !important + } + .flex-lg-wrap { + flex-wrap: wrap !important + } + .flex-lg-nowrap { + flex-wrap: nowrap !important + } + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important + } + .flex-lg-fill { + flex: 1 1 auto !important + } + .flex-lg-grow-0 { + flex-grow: 0 !important + } + .flex-lg-grow-1 { + flex-grow: 1 !important + } + .flex-lg-shrink-0 { + flex-shrink: 0 !important + } + .flex-lg-shrink-1 { + flex-shrink: 1 !important + } + .justify-content-lg-start { + justify-content: flex-start !important + } + .justify-content-lg-end { + justify-content: flex-end !important + } + .justify-content-lg-center { + justify-content: center !important + } + .justify-content-lg-between { + justify-content: space-between !important + } + .justify-content-lg-around { + justify-content: space-around !important + } + .align-items-lg-start { + align-items: flex-start !important + } + .align-items-lg-end { + align-items: flex-end !important + } + .align-items-lg-center { + align-items: center !important + } + .align-items-lg-baseline { + align-items: baseline !important + } + .align-items-lg-stretch { + align-items: stretch !important + } + .align-content-lg-start { + align-content: flex-start !important + } + .align-content-lg-end { + align-content: flex-end !important + } + .align-content-lg-center { + align-content: center !important + } + .align-content-lg-between { + align-content: space-between !important + } + .align-content-lg-around { + align-content: space-around !important + } + .align-content-lg-stretch { + align-content: stretch !important + } + .align-self-lg-auto { + align-self: auto !important + } + .align-self-lg-start { + align-self: flex-start !important + } + .align-self-lg-end { + align-self: flex-end !important + } + .align-self-lg-center { + align-self: center !important + } + .align-self-lg-baseline { + align-self: baseline !important + } + .align-self-lg-stretch { + align-self: stretch !important + } +} + +@media ( min-width :1200px) { + .flex-xl-row { + flex-direction: row !important + } + .flex-xl-column { + flex-direction: column !important + } + .flex-xl-row-reverse { + flex-direction: row-reverse !important + } + .flex-xl-column-reverse { + flex-direction: column-reverse !important + } + .flex-xl-wrap { + flex-wrap: wrap !important + } + .flex-xl-nowrap { + flex-wrap: nowrap !important + } + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + .flex-xl-fill { + flex: 1 1 auto !important + } + .flex-xl-grow-0 { + flex-grow: 0 !important + } + .flex-xl-grow-1 { + flex-grow: 1 !important + } + .flex-xl-shrink-0 { + flex-shrink: 0 !important + } + .flex-xl-shrink-1 { + flex-shrink: 1 !important + } + .justify-content-xl-start { + justify-content: flex-start !important + } + .justify-content-xl-end { + justify-content: flex-end !important + } + .justify-content-xl-center { + justify-content: center !important + } + .justify-content-xl-between { + justify-content: space-between !important + } + .justify-content-xl-around { + justify-content: space-around !important + } + .align-items-xl-start { + align-items: flex-start !important + } + .align-items-xl-end { + align-items: flex-end !important + } + .align-items-xl-center { + align-items: center !important + } + .align-items-xl-baseline { + align-items: baseline !important + } + .align-items-xl-stretch { + align-items: stretch !important + } + .align-content-xl-start { + align-content: flex-start !important + } + .align-content-xl-end { + align-content: flex-end !important + } + .align-content-xl-center { + align-content: center !important + } + .align-content-xl-between { + align-content: space-between !important + } + .align-content-xl-around { + align-content: space-around !important + } + .align-content-xl-stretch { + align-content: stretch !important + } + .align-self-xl-auto { + align-self: auto !important + } + .align-self-xl-start { + align-self: flex-start !important + } + .align-self-xl-end { + align-self: flex-end !important + } + .align-self-xl-center { + align-self: center !important + } + .align-self-xl-baseline { + align-self: baseline !important + } + .align-self-xl-stretch { + align-self: stretch !important + } +} + +.float-left { + float: left !important +} + +.float-right { + float: right !important +} + +.float-none { + float: none !important +} + +@media ( min-width :576px) { + .float-sm-left { + float: left !important + } + .float-sm-right { + float: right !important + } + .float-sm-none { + float: none !important + } +} + +@media ( min-width :768px) { + .float-md-left { + float: left !important + } + .float-md-right { + float: right !important + } + .float-md-none { + float: none !important + } +} + +@media ( min-width :992px) { + .float-lg-left { + float: left !important + } + .float-lg-right { + float: right !important + } + .float-lg-none { + float: none !important + } +} + +@media ( min-width :1200px) { + .float-xl-left { + float: left !important + } + .float-xl-right { + float: right !important + } + .float-xl-none { + float: none !important + } +} + +.overflow-auto { + overflow: auto !important +} + +.overflow-hidden { + overflow: hidden !important +} + +.position-static { + position: static !important +} + +.position-relative { + position: relative !important +} + +.position-absolute { + position: absolute !important +} + +.position-fixed { + position: fixed !important +} + +.position-sticky { + position: sticky !important +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030 +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030 +} + +@ +supports (position:sticky ){ . + sticky-top {position: sticky; + top: 0; + z-index: 1020 +} + +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0 +} + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal +} + +.shadow-sm { + box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075) !important +} + +.shadow { + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15) !important +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, .175) !important +} + +.shadow-none { + box-shadow: none !important +} + +.w-25 { + width: 25% !important +} + +.w-50 { + width: 50% !important +} + +.w-75 { + width: 75% !important +} + +.w-100 { + width: 100% !important +} + +.w-auto { + width: auto !important +} + +.h-25 { + height: 25% !important +} + +.h-50 { + height: 50% !important +} + +.h-75 { + height: 75% !important +} + +.h-100 { + height: 100% !important +} + +.h-auto { + height: auto !important +} + +.mw-100 { + max-width: 100% !important +} + +.mh-100 { + max-height: 100% !important +} + +.min-vw-100 { + min-width: 100vw !important +} + +.min-vh-100 { + min-height: 100vh !important +} + +.vw-100 { + width: 100vw !important +} + +.vh-100 { + height: 100vh !important +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + pointer-events: auto; + content: ""; + background-color: rgba(0, 0, 0, 0) +} + +.m-0 { + margin: 0 !important +} + +.mt-0, .my-0 { + margin-top: 0 !important +} + +.mr-0, .mx-0 { + margin-right: 0 !important +} + +.mb-0, .my-0 { + margin-bottom: 0 !important +} + +.ml-0, .mx-0 { + margin-left: 0 !important +} + +.m-1 { + margin: .25rem !important +} + +.mt-1, .my-1 { + margin-top: .25rem !important +} + +.mr-1, .mx-1 { + margin-right: .25rem !important +} + +.mb-1, .my-1 { + margin-bottom: .25rem !important +} + +.ml-1, .mx-1 { + margin-left: .25rem !important +} + +.m-2 { + margin: .5rem !important +} + +.mt-2, .my-2 { + margin-top: .5rem !important +} + +.mr-2, .mx-2 { + margin-right: .5rem !important +} + +.mb-2, .my-2 { + margin-bottom: .5rem !important +} + +.ml-2, .mx-2 { + margin-left: .5rem !important +} + +.m-3 { + margin: 1rem !important +} + +.mt-3, .my-3 { + margin-top: 1rem !important +} + +.mr-3, .mx-3 { + margin-right: 1rem !important +} + +.mb-3, .my-3 { + margin-bottom: 1rem !important +} + +.ml-3, .mx-3 { + margin-left: 1rem !important +} + +.m-4 { + margin: 1.5rem !important +} + +.mt-4, .my-4 { + margin-top: 1.5rem !important +} + +.mr-4, .mx-4 { + margin-right: 1.5rem !important +} + +.mb-4, .my-4 { + margin-bottom: 1.5rem !important +} + +.ml-4, .mx-4 { + margin-left: 1.5rem !important +} + +.m-5 { + margin: 3rem !important +} + +.mt-5, .my-5 { + margin-top: 3rem !important +} + +.mr-5, .mx-5 { + margin-right: 3rem !important +} + +.mb-5, .my-5 { + margin-bottom: 3rem !important +} + +.ml-5, .mx-5 { + margin-left: 3rem !important +} + +.p-0 { + padding: 0 !important +} + +.pt-0, .py-0 { + padding-top: 0 !important +} + +.pr-0, .px-0 { + padding-right: 0 !important +} + +.pb-0, .py-0 { + padding-bottom: 0 !important +} + +.pl-0, .px-0 { + padding-left: 0 !important +} + +.p-1 { + padding: .25rem !important +} + +.pt-1, .py-1 { + padding-top: .25rem !important +} + +.pr-1, .px-1 { + padding-right: .25rem !important +} + +.pb-1, .py-1 { + padding-bottom: .25rem !important +} + +.pl-1, .px-1 { + padding-left: .25rem !important +} + +.p-2 { + padding: .5rem !important +} + +.pt-2, .py-2 { + padding-top: .5rem !important +} + +.pr-2, .px-2 { + padding-right: .5rem !important +} + +.pb-2, .py-2 { + padding-bottom: .5rem !important +} + +.pl-2, .px-2 { + padding-left: .5rem !important +} + +.p-3 { + padding: 1rem !important +} + +.pt-3, .py-3 { + padding-top: 1rem !important +} + +.pr-3, .px-3 { + padding-right: 1rem !important +} + +.pb-3, .py-3 { + padding-bottom: 1rem !important +} + +.pl-3, .px-3 { + padding-left: 1rem !important +} + +.p-4 { + padding: 1.5rem !important +} + +.pt-4, .py-4 { + padding-top: 1.5rem !important +} + +.pr-4, .px-4 { + padding-right: 1.5rem !important +} + +.pb-4, .py-4 { + padding-bottom: 1.5rem !important +} + +.pl-4, .px-4 { + padding-left: 1.5rem !important +} + +.p-5 { + padding: 3rem !important +} + +.pt-5, .py-5 { + padding-top: 3rem !important +} + +.pr-5, .px-5 { + padding-right: 3rem !important +} + +.pb-5, .py-5 { + padding-bottom: 3rem !important +} + +.pl-5, .px-5 { + padding-left: 3rem !important +} + +.m-n1 { + margin: -.25rem !important +} + +.mt-n1, .my-n1 { + margin-top: -.25rem !important +} + +.mr-n1, .mx-n1 { + margin-right: -.25rem !important +} + +.mb-n1, .my-n1 { + margin-bottom: -.25rem !important +} + +.ml-n1, .mx-n1 { + margin-left: -.25rem !important +} + +.m-n2 { + margin: -.5rem !important +} + +.mt-n2, .my-n2 { + margin-top: -.5rem !important +} + +.mr-n2, .mx-n2 { + margin-right: -.5rem !important +} + +.mb-n2, .my-n2 { + margin-bottom: -.5rem !important +} + +.ml-n2, .mx-n2 { + margin-left: -.5rem !important +} + +.m-n3 { + margin: -1rem !important +} + +.mt-n3, .my-n3 { + margin-top: -1rem !important +} + +.mr-n3, .mx-n3 { + margin-right: -1rem !important +} + +.mb-n3, .my-n3 { + margin-bottom: -1rem !important +} + +.ml-n3, .mx-n3 { + margin-left: -1rem !important +} + +.m-n4 { + margin: -1.5rem !important +} + +.mt-n4, .my-n4 { + margin-top: -1.5rem !important +} + +.mr-n4, .mx-n4 { + margin-right: -1.5rem !important +} + +.mb-n4, .my-n4 { + margin-bottom: -1.5rem !important +} + +.ml-n4, .mx-n4 { + margin-left: -1.5rem !important +} + +.m-n5 { + margin: -3rem !important +} + +.mt-n5, .my-n5 { + margin-top: -3rem !important +} + +.mr-n5, .mx-n5 { + margin-right: -3rem !important +} + +.mb-n5, .my-n5 { + margin-bottom: -3rem !important +} + +.ml-n5, .mx-n5 { + margin-left: -3rem !important +} + +.m-auto { + margin: auto !important +} + +.mt-auto, .my-auto { + margin-top: auto !important +} + +.mr-auto, .mx-auto { + margin-right: auto !important +} + +.mb-auto, .my-auto { + margin-bottom: auto !important +} + +.ml-auto, .mx-auto { + margin-left: auto !important +} + +@media ( min-width :576px) { + .m-sm-0 { + margin: 0 !important + } + .mt-sm-0, .my-sm-0 { + margin-top: 0 !important + } + .mr-sm-0, .mx-sm-0 { + margin-right: 0 !important + } + .mb-sm-0, .my-sm-0 { + margin-bottom: 0 !important + } + .ml-sm-0, .mx-sm-0 { + margin-left: 0 !important + } + .m-sm-1 { + margin: .25rem !important + } + .mt-sm-1, .my-sm-1 { + margin-top: .25rem !important + } + .mr-sm-1, .mx-sm-1 { + margin-right: .25rem !important + } + .mb-sm-1, .my-sm-1 { + margin-bottom: .25rem !important + } + .ml-sm-1, .mx-sm-1 { + margin-left: .25rem !important + } + .m-sm-2 { + margin: .5rem !important + } + .mt-sm-2, .my-sm-2 { + margin-top: .5rem !important + } + .mr-sm-2, .mx-sm-2 { + margin-right: .5rem !important + } + .mb-sm-2, .my-sm-2 { + margin-bottom: .5rem !important + } + .ml-sm-2, .mx-sm-2 { + margin-left: .5rem !important + } + .m-sm-3 { + margin: 1rem !important + } + .mt-sm-3, .my-sm-3 { + margin-top: 1rem !important + } + .mr-sm-3, .mx-sm-3 { + margin-right: 1rem !important + } + .mb-sm-3, .my-sm-3 { + margin-bottom: 1rem !important + } + .ml-sm-3, .mx-sm-3 { + margin-left: 1rem !important + } + .m-sm-4 { + margin: 1.5rem !important + } + .mt-sm-4, .my-sm-4 { + margin-top: 1.5rem !important + } + .mr-sm-4, .mx-sm-4 { + margin-right: 1.5rem !important + } + .mb-sm-4, .my-sm-4 { + margin-bottom: 1.5rem !important + } + .ml-sm-4, .mx-sm-4 { + margin-left: 1.5rem !important + } + .m-sm-5 { + margin: 3rem !important + } + .mt-sm-5, .my-sm-5 { + margin-top: 3rem !important + } + .mr-sm-5, .mx-sm-5 { + margin-right: 3rem !important + } + .mb-sm-5, .my-sm-5 { + margin-bottom: 3rem !important + } + .ml-sm-5, .mx-sm-5 { + margin-left: 3rem !important + } + .p-sm-0 { + padding: 0 !important + } + .pt-sm-0, .py-sm-0 { + padding-top: 0 !important + } + .pr-sm-0, .px-sm-0 { + padding-right: 0 !important + } + .pb-sm-0, .py-sm-0 { + padding-bottom: 0 !important + } + .pl-sm-0, .px-sm-0 { + padding-left: 0 !important + } + .p-sm-1 { + padding: .25rem !important + } + .pt-sm-1, .py-sm-1 { + padding-top: .25rem !important + } + .pr-sm-1, .px-sm-1 { + padding-right: .25rem !important + } + .pb-sm-1, .py-sm-1 { + padding-bottom: .25rem !important + } + .pl-sm-1, .px-sm-1 { + padding-left: .25rem !important + } + .p-sm-2 { + padding: .5rem !important + } + .pt-sm-2, .py-sm-2 { + padding-top: .5rem !important + } + .pr-sm-2, .px-sm-2 { + padding-right: .5rem !important + } + .pb-sm-2, .py-sm-2 { + padding-bottom: .5rem !important + } + .pl-sm-2, .px-sm-2 { + padding-left: .5rem !important + } + .p-sm-3 { + padding: 1rem !important + } + .pt-sm-3, .py-sm-3 { + padding-top: 1rem !important + } + .pr-sm-3, .px-sm-3 { + padding-right: 1rem !important + } + .pb-sm-3, .py-sm-3 { + padding-bottom: 1rem !important + } + .pl-sm-3, .px-sm-3 { + padding-left: 1rem !important + } + .p-sm-4 { + padding: 1.5rem !important + } + .pt-sm-4, .py-sm-4 { + padding-top: 1.5rem !important + } + .pr-sm-4, .px-sm-4 { + padding-right: 1.5rem !important + } + .pb-sm-4, .py-sm-4 { + padding-bottom: 1.5rem !important + } + .pl-sm-4, .px-sm-4 { + padding-left: 1.5rem !important + } + .p-sm-5 { + padding: 3rem !important + } + .pt-sm-5, .py-sm-5 { + padding-top: 3rem !important + } + .pr-sm-5, .px-sm-5 { + padding-right: 3rem !important + } + .pb-sm-5, .py-sm-5 { + padding-bottom: 3rem !important + } + .pl-sm-5, .px-sm-5 { + padding-left: 3rem !important + } + .m-sm-n1 { + margin: -.25rem !important + } + .mt-sm-n1, .my-sm-n1 { + margin-top: -.25rem !important + } + .mr-sm-n1, .mx-sm-n1 { + margin-right: -.25rem !important + } + .mb-sm-n1, .my-sm-n1 { + margin-bottom: -.25rem !important + } + .ml-sm-n1, .mx-sm-n1 { + margin-left: -.25rem !important + } + .m-sm-n2 { + margin: -.5rem !important + } + .mt-sm-n2, .my-sm-n2 { + margin-top: -.5rem !important + } + .mr-sm-n2, .mx-sm-n2 { + margin-right: -.5rem !important + } + .mb-sm-n2, .my-sm-n2 { + margin-bottom: -.5rem !important + } + .ml-sm-n2, .mx-sm-n2 { + margin-left: -.5rem !important + } + .m-sm-n3 { + margin: -1rem !important + } + .mt-sm-n3, .my-sm-n3 { + margin-top: -1rem !important + } + .mr-sm-n3, .mx-sm-n3 { + margin-right: -1rem !important + } + .mb-sm-n3, .my-sm-n3 { + margin-bottom: -1rem !important + } + .ml-sm-n3, .mx-sm-n3 { + margin-left: -1rem !important + } + .m-sm-n4 { + margin: -1.5rem !important + } + .mt-sm-n4, .my-sm-n4 { + margin-top: -1.5rem !important + } + .mr-sm-n4, .mx-sm-n4 { + margin-right: -1.5rem !important + } + .mb-sm-n4, .my-sm-n4 { + margin-bottom: -1.5rem !important + } + .ml-sm-n4, .mx-sm-n4 { + margin-left: -1.5rem !important + } + .m-sm-n5 { + margin: -3rem !important + } + .mt-sm-n5, .my-sm-n5 { + margin-top: -3rem !important + } + .mr-sm-n5, .mx-sm-n5 { + margin-right: -3rem !important + } + .mb-sm-n5, .my-sm-n5 { + margin-bottom: -3rem !important + } + .ml-sm-n5, .mx-sm-n5 { + margin-left: -3rem !important + } + .m-sm-auto { + margin: auto !important + } + .mt-sm-auto, .my-sm-auto { + margin-top: auto !important + } + .mr-sm-auto, .mx-sm-auto { + margin-right: auto !important + } + .mb-sm-auto, .my-sm-auto { + margin-bottom: auto !important + } + .ml-sm-auto, .mx-sm-auto { + margin-left: auto !important + } +} + +@media ( min-width :768px) { + .m-md-0 { + margin: 0 !important + } + .mt-md-0, .my-md-0 { + margin-top: 0 !important + } + .mr-md-0, .mx-md-0 { + margin-right: 0 !important + } + .mb-md-0, .my-md-0 { + margin-bottom: 0 !important + } + .ml-md-0, .mx-md-0 { + margin-left: 0 !important + } + .m-md-1 { + margin: .25rem !important + } + .mt-md-1, .my-md-1 { + margin-top: .25rem !important + } + .mr-md-1, .mx-md-1 { + margin-right: .25rem !important + } + .mb-md-1, .my-md-1 { + margin-bottom: .25rem !important + } + .ml-md-1, .mx-md-1 { + margin-left: .25rem !important + } + .m-md-2 { + margin: .5rem !important + } + .mt-md-2, .my-md-2 { + margin-top: .5rem !important + } + .mr-md-2, .mx-md-2 { + margin-right: .5rem !important + } + .mb-md-2, .my-md-2 { + margin-bottom: .5rem !important + } + .ml-md-2, .mx-md-2 { + margin-left: .5rem !important + } + .m-md-3 { + margin: 1rem !important + } + .mt-md-3, .my-md-3 { + margin-top: 1rem !important + } + .mr-md-3, .mx-md-3 { + margin-right: 1rem !important + } + .mb-md-3, .my-md-3 { + margin-bottom: 1rem !important + } + .ml-md-3, .mx-md-3 { + margin-left: 1rem !important + } + .m-md-4 { + margin: 1.5rem !important + } + .mt-md-4, .my-md-4 { + margin-top: 1.5rem !important + } + .mr-md-4, .mx-md-4 { + margin-right: 1.5rem !important + } + .mb-md-4, .my-md-4 { + margin-bottom: 1.5rem !important + } + .ml-md-4, .mx-md-4 { + margin-left: 1.5rem !important + } + .m-md-5 { + margin: 3rem !important + } + .mt-md-5, .my-md-5 { + margin-top: 3rem !important + } + .mr-md-5, .mx-md-5 { + margin-right: 3rem !important + } + .mb-md-5, .my-md-5 { + margin-bottom: 3rem !important + } + .ml-md-5, .mx-md-5 { + margin-left: 3rem !important + } + .p-md-0 { + padding: 0 !important + } + .pt-md-0, .py-md-0 { + padding-top: 0 !important + } + .pr-md-0, .px-md-0 { + padding-right: 0 !important + } + .pb-md-0, .py-md-0 { + padding-bottom: 0 !important + } + .pl-md-0, .px-md-0 { + padding-left: 0 !important + } + .p-md-1 { + padding: .25rem !important + } + .pt-md-1, .py-md-1 { + padding-top: .25rem !important + } + .pr-md-1, .px-md-1 { + padding-right: .25rem !important + } + .pb-md-1, .py-md-1 { + padding-bottom: .25rem !important + } + .pl-md-1, .px-md-1 { + padding-left: .25rem !important + } + .p-md-2 { + padding: .5rem !important + } + .pt-md-2, .py-md-2 { + padding-top: .5rem !important + } + .pr-md-2, .px-md-2 { + padding-right: .5rem !important + } + .pb-md-2, .py-md-2 { + padding-bottom: .5rem !important + } + .pl-md-2, .px-md-2 { + padding-left: .5rem !important + } + .p-md-3 { + padding: 1rem !important + } + .pt-md-3, .py-md-3 { + padding-top: 1rem !important + } + .pr-md-3, .px-md-3 { + padding-right: 1rem !important + } + .pb-md-3, .py-md-3 { + padding-bottom: 1rem !important + } + .pl-md-3, .px-md-3 { + padding-left: 1rem !important + } + .p-md-4 { + padding: 1.5rem !important + } + .pt-md-4, .py-md-4 { + padding-top: 1.5rem !important + } + .pr-md-4, .px-md-4 { + padding-right: 1.5rem !important + } + .pb-md-4, .py-md-4 { + padding-bottom: 1.5rem !important + } + .pl-md-4, .px-md-4 { + padding-left: 1.5rem !important + } + .p-md-5 { + padding: 3rem !important + } + .pt-md-5, .py-md-5 { + padding-top: 3rem !important + } + .pr-md-5, .px-md-5 { + padding-right: 3rem !important + } + .pb-md-5, .py-md-5 { + padding-bottom: 3rem !important + } + .pl-md-5, .px-md-5 { + padding-left: 3rem !important + } + .m-md-n1 { + margin: -.25rem !important + } + .mt-md-n1, .my-md-n1 { + margin-top: -.25rem !important + } + .mr-md-n1, .mx-md-n1 { + margin-right: -.25rem !important + } + .mb-md-n1, .my-md-n1 { + margin-bottom: -.25rem !important + } + .ml-md-n1, .mx-md-n1 { + margin-left: -.25rem !important + } + .m-md-n2 { + margin: -.5rem !important + } + .mt-md-n2, .my-md-n2 { + margin-top: -.5rem !important + } + .mr-md-n2, .mx-md-n2 { + margin-right: -.5rem !important + } + .mb-md-n2, .my-md-n2 { + margin-bottom: -.5rem !important + } + .ml-md-n2, .mx-md-n2 { + margin-left: -.5rem !important + } + .m-md-n3 { + margin: -1rem !important + } + .mt-md-n3, .my-md-n3 { + margin-top: -1rem !important + } + .mr-md-n3, .mx-md-n3 { + margin-right: -1rem !important + } + .mb-md-n3, .my-md-n3 { + margin-bottom: -1rem !important + } + .ml-md-n3, .mx-md-n3 { + margin-left: -1rem !important + } + .m-md-n4 { + margin: -1.5rem !important + } + .mt-md-n4, .my-md-n4 { + margin-top: -1.5rem !important + } + .mr-md-n4, .mx-md-n4 { + margin-right: -1.5rem !important + } + .mb-md-n4, .my-md-n4 { + margin-bottom: -1.5rem !important + } + .ml-md-n4, .mx-md-n4 { + margin-left: -1.5rem !important + } + .m-md-n5 { + margin: -3rem !important + } + .mt-md-n5, .my-md-n5 { + margin-top: -3rem !important + } + .mr-md-n5, .mx-md-n5 { + margin-right: -3rem !important + } + .mb-md-n5, .my-md-n5 { + margin-bottom: -3rem !important + } + .ml-md-n5, .mx-md-n5 { + margin-left: -3rem !important + } + .m-md-auto { + margin: auto !important + } + .mt-md-auto, .my-md-auto { + margin-top: auto !important + } + .mr-md-auto, .mx-md-auto { + margin-right: auto !important + } + .mb-md-auto, .my-md-auto { + margin-bottom: auto !important + } + .ml-md-auto, .mx-md-auto { + margin-left: auto !important + } +} + +@media ( min-width :992px) { + .m-lg-0 { + margin: 0 !important + } + .mt-lg-0, .my-lg-0 { + margin-top: 0 !important + } + .mr-lg-0, .mx-lg-0 { + margin-right: 0 !important + } + .mb-lg-0, .my-lg-0 { + margin-bottom: 0 !important + } + .ml-lg-0, .mx-lg-0 { + margin-left: 0 !important + } + .m-lg-1 { + margin: .25rem !important + } + .mt-lg-1, .my-lg-1 { + margin-top: .25rem !important + } + .mr-lg-1, .mx-lg-1 { + margin-right: .25rem !important + } + .mb-lg-1, .my-lg-1 { + margin-bottom: .25rem !important + } + .ml-lg-1, .mx-lg-1 { + margin-left: .25rem !important + } + .m-lg-2 { + margin: .5rem !important + } + .mt-lg-2, .my-lg-2 { + margin-top: .5rem !important + } + .mr-lg-2, .mx-lg-2 { + margin-right: .5rem !important + } + .mb-lg-2, .my-lg-2 { + margin-bottom: .5rem !important + } + .ml-lg-2, .mx-lg-2 { + margin-left: .5rem !important + } + .m-lg-3 { + margin: 1rem !important + } + .mt-lg-3, .my-lg-3 { + margin-top: 1rem !important + } + .mr-lg-3, .mx-lg-3 { + margin-right: 1rem !important + } + .mb-lg-3, .my-lg-3 { + margin-bottom: 1rem !important + } + .ml-lg-3, .mx-lg-3 { + margin-left: 1rem !important + } + .m-lg-4 { + margin: 1.5rem !important + } + .mt-lg-4, .my-lg-4 { + margin-top: 1.5rem !important + } + .mr-lg-4, .mx-lg-4 { + margin-right: 1.5rem !important + } + .mb-lg-4, .my-lg-4 { + margin-bottom: 1.5rem !important + } + .ml-lg-4, .mx-lg-4 { + margin-left: 1.5rem !important + } + .m-lg-5 { + margin: 3rem !important + } + .mt-lg-5, .my-lg-5 { + margin-top: 3rem !important + } + .mr-lg-5, .mx-lg-5 { + margin-right: 3rem !important + } + .mb-lg-5, .my-lg-5 { + margin-bottom: 3rem !important + } + .ml-lg-5, .mx-lg-5 { + margin-left: 3rem !important + } + .p-lg-0 { + padding: 0 !important + } + .pt-lg-0, .py-lg-0 { + padding-top: 0 !important + } + .pr-lg-0, .px-lg-0 { + padding-right: 0 !important + } + .pb-lg-0, .py-lg-0 { + padding-bottom: 0 !important + } + .pl-lg-0, .px-lg-0 { + padding-left: 0 !important + } + .p-lg-1 { + padding: .25rem !important + } + .pt-lg-1, .py-lg-1 { + padding-top: .25rem !important + } + .pr-lg-1, .px-lg-1 { + padding-right: .25rem !important + } + .pb-lg-1, .py-lg-1 { + padding-bottom: .25rem !important + } + .pl-lg-1, .px-lg-1 { + padding-left: .25rem !important + } + .p-lg-2 { + padding: .5rem !important + } + .pt-lg-2, .py-lg-2 { + padding-top: .5rem !important + } + .pr-lg-2, .px-lg-2 { + padding-right: .5rem !important + } + .pb-lg-2, .py-lg-2 { + padding-bottom: .5rem !important + } + .pl-lg-2, .px-lg-2 { + padding-left: .5rem !important + } + .p-lg-3 { + padding: 1rem !important + } + .pt-lg-3, .py-lg-3 { + padding-top: 1rem !important + } + .pr-lg-3, .px-lg-3 { + padding-right: 1rem !important + } + .pb-lg-3, .py-lg-3 { + padding-bottom: 1rem !important + } + .pl-lg-3, .px-lg-3 { + padding-left: 1rem !important + } + .p-lg-4 { + padding: 1.5rem !important + } + .pt-lg-4, .py-lg-4 { + padding-top: 1.5rem !important + } + .pr-lg-4, .px-lg-4 { + padding-right: 1.5rem !important + } + .pb-lg-4, .py-lg-4 { + padding-bottom: 1.5rem !important + } + .pl-lg-4, .px-lg-4 { + padding-left: 1.5rem !important + } + .p-lg-5 { + padding: 3rem !important + } + .pt-lg-5, .py-lg-5 { + padding-top: 3rem !important + } + .pr-lg-5, .px-lg-5 { + padding-right: 3rem !important + } + .pb-lg-5, .py-lg-5 { + padding-bottom: 3rem !important + } + .pl-lg-5, .px-lg-5 { + padding-left: 3rem !important + } + .m-lg-n1 { + margin: -.25rem !important + } + .mt-lg-n1, .my-lg-n1 { + margin-top: -.25rem !important + } + .mr-lg-n1, .mx-lg-n1 { + margin-right: -.25rem !important + } + .mb-lg-n1, .my-lg-n1 { + margin-bottom: -.25rem !important + } + .ml-lg-n1, .mx-lg-n1 { + margin-left: -.25rem !important + } + .m-lg-n2 { + margin: -.5rem !important + } + .mt-lg-n2, .my-lg-n2 { + margin-top: -.5rem !important + } + .mr-lg-n2, .mx-lg-n2 { + margin-right: -.5rem !important + } + .mb-lg-n2, .my-lg-n2 { + margin-bottom: -.5rem !important + } + .ml-lg-n2, .mx-lg-n2 { + margin-left: -.5rem !important + } + .m-lg-n3 { + margin: -1rem !important + } + .mt-lg-n3, .my-lg-n3 { + margin-top: -1rem !important + } + .mr-lg-n3, .mx-lg-n3 { + margin-right: -1rem !important + } + .mb-lg-n3, .my-lg-n3 { + margin-bottom: -1rem !important + } + .ml-lg-n3, .mx-lg-n3 { + margin-left: -1rem !important + } + .m-lg-n4 { + margin: -1.5rem !important + } + .mt-lg-n4, .my-lg-n4 { + margin-top: -1.5rem !important + } + .mr-lg-n4, .mx-lg-n4 { + margin-right: -1.5rem !important + } + .mb-lg-n4, .my-lg-n4 { + margin-bottom: -1.5rem !important + } + .ml-lg-n4, .mx-lg-n4 { + margin-left: -1.5rem !important + } + .m-lg-n5 { + margin: -3rem !important + } + .mt-lg-n5, .my-lg-n5 { + margin-top: -3rem !important + } + .mr-lg-n5, .mx-lg-n5 { + margin-right: -3rem !important + } + .mb-lg-n5, .my-lg-n5 { + margin-bottom: -3rem !important + } + .ml-lg-n5, .mx-lg-n5 { + margin-left: -3rem !important + } + .m-lg-auto { + margin: auto !important + } + .mt-lg-auto, .my-lg-auto { + margin-top: auto !important + } + .mr-lg-auto, .mx-lg-auto { + margin-right: auto !important + } + .mb-lg-auto, .my-lg-auto { + margin-bottom: auto !important + } + .ml-lg-auto, .mx-lg-auto { + margin-left: auto !important + } +} + +@media ( min-width :1200px) { + .m-xl-0 { + margin: 0 !important + } + .mt-xl-0, .my-xl-0 { + margin-top: 0 !important + } + .mr-xl-0, .mx-xl-0 { + margin-right: 0 !important + } + .mb-xl-0, .my-xl-0 { + margin-bottom: 0 !important + } + .ml-xl-0, .mx-xl-0 { + margin-left: 0 !important + } + .m-xl-1 { + margin: .25rem !important + } + .mt-xl-1, .my-xl-1 { + margin-top: .25rem !important + } + .mr-xl-1, .mx-xl-1 { + margin-right: .25rem !important + } + .mb-xl-1, .my-xl-1 { + margin-bottom: .25rem !important + } + .ml-xl-1, .mx-xl-1 { + margin-left: .25rem !important + } + .m-xl-2 { + margin: .5rem !important + } + .mt-xl-2, .my-xl-2 { + margin-top: .5rem !important + } + .mr-xl-2, .mx-xl-2 { + margin-right: .5rem !important + } + .mb-xl-2, .my-xl-2 { + margin-bottom: .5rem !important + } + .ml-xl-2, .mx-xl-2 { + margin-left: .5rem !important + } + .m-xl-3 { + margin: 1rem !important + } + .mt-xl-3, .my-xl-3 { + margin-top: 1rem !important + } + .mr-xl-3, .mx-xl-3 { + margin-right: 1rem !important + } + .mb-xl-3, .my-xl-3 { + margin-bottom: 1rem !important + } + .ml-xl-3, .mx-xl-3 { + margin-left: 1rem !important + } + .m-xl-4 { + margin: 1.5rem !important + } + .mt-xl-4, .my-xl-4 { + margin-top: 1.5rem !important + } + .mr-xl-4, .mx-xl-4 { + margin-right: 1.5rem !important + } + .mb-xl-4, .my-xl-4 { + margin-bottom: 1.5rem !important + } + .ml-xl-4, .mx-xl-4 { + margin-left: 1.5rem !important + } + .m-xl-5 { + margin: 3rem !important + } + .mt-xl-5, .my-xl-5 { + margin-top: 3rem !important + } + .mr-xl-5, .mx-xl-5 { + margin-right: 3rem !important + } + .mb-xl-5, .my-xl-5 { + margin-bottom: 3rem !important + } + .ml-xl-5, .mx-xl-5 { + margin-left: 3rem !important + } + .p-xl-0 { + padding: 0 !important + } + .pt-xl-0, .py-xl-0 { + padding-top: 0 !important + } + .pr-xl-0, .px-xl-0 { + padding-right: 0 !important + } + .pb-xl-0, .py-xl-0 { + padding-bottom: 0 !important + } + .pl-xl-0, .px-xl-0 { + padding-left: 0 !important + } + .p-xl-1 { + padding: .25rem !important + } + .pt-xl-1, .py-xl-1 { + padding-top: .25rem !important + } + .pr-xl-1, .px-xl-1 { + padding-right: .25rem !important + } + .pb-xl-1, .py-xl-1 { + padding-bottom: .25rem !important + } + .pl-xl-1, .px-xl-1 { + padding-left: .25rem !important + } + .p-xl-2 { + padding: .5rem !important + } + .pt-xl-2, .py-xl-2 { + padding-top: .5rem !important + } + .pr-xl-2, .px-xl-2 { + padding-right: .5rem !important + } + .pb-xl-2, .py-xl-2 { + padding-bottom: .5rem !important + } + .pl-xl-2, .px-xl-2 { + padding-left: .5rem !important + } + .p-xl-3 { + padding: 1rem !important + } + .pt-xl-3, .py-xl-3 { + padding-top: 1rem !important + } + .pr-xl-3, .px-xl-3 { + padding-right: 1rem !important + } + .pb-xl-3, .py-xl-3 { + padding-bottom: 1rem !important + } + .pl-xl-3, .px-xl-3 { + padding-left: 1rem !important + } + .p-xl-4 { + padding: 1.5rem !important + } + .pt-xl-4, .py-xl-4 { + padding-top: 1.5rem !important + } + .pr-xl-4, .px-xl-4 { + padding-right: 1.5rem !important + } + .pb-xl-4, .py-xl-4 { + padding-bottom: 1.5rem !important + } + .pl-xl-4, .px-xl-4 { + padding-left: 1.5rem !important + } + .p-xl-5 { + padding: 3rem !important + } + .pt-xl-5, .py-xl-5 { + padding-top: 3rem !important + } + .pr-xl-5, .px-xl-5 { + padding-right: 3rem !important + } + .pb-xl-5, .py-xl-5 { + padding-bottom: 3rem !important + } + .pl-xl-5, .px-xl-5 { + padding-left: 3rem !important + } + .m-xl-n1 { + margin: -.25rem !important + } + .mt-xl-n1, .my-xl-n1 { + margin-top: -.25rem !important + } + .mr-xl-n1, .mx-xl-n1 { + margin-right: -.25rem !important + } + .mb-xl-n1, .my-xl-n1 { + margin-bottom: -.25rem !important + } + .ml-xl-n1, .mx-xl-n1 { + margin-left: -.25rem !important + } + .m-xl-n2 { + margin: -.5rem !important + } + .mt-xl-n2, .my-xl-n2 { + margin-top: -.5rem !important + } + .mr-xl-n2, .mx-xl-n2 { + margin-right: -.5rem !important + } + .mb-xl-n2, .my-xl-n2 { + margin-bottom: -.5rem !important + } + .ml-xl-n2, .mx-xl-n2 { + margin-left: -.5rem !important + } + .m-xl-n3 { + margin: -1rem !important + } + .mt-xl-n3, .my-xl-n3 { + margin-top: -1rem !important + } + .mr-xl-n3, .mx-xl-n3 { + margin-right: -1rem !important + } + .mb-xl-n3, .my-xl-n3 { + margin-bottom: -1rem !important + } + .ml-xl-n3, .mx-xl-n3 { + margin-left: -1rem !important + } + .m-xl-n4 { + margin: -1.5rem !important + } + .mt-xl-n4, .my-xl-n4 { + margin-top: -1.5rem !important + } + .mr-xl-n4, .mx-xl-n4 { + margin-right: -1.5rem !important + } + .mb-xl-n4, .my-xl-n4 { + margin-bottom: -1.5rem !important + } + .ml-xl-n4, .mx-xl-n4 { + margin-left: -1.5rem !important + } + .m-xl-n5 { + margin: -3rem !important + } + .mt-xl-n5, .my-xl-n5 { + margin-top: -3rem !important + } + .mr-xl-n5, .mx-xl-n5 { + margin-right: -3rem !important + } + .mb-xl-n5, .my-xl-n5 { + margin-bottom: -3rem !important + } + .ml-xl-n5, .mx-xl-n5 { + margin-left: -3rem !important + } + .m-xl-auto { + margin: auto !important + } + .mt-xl-auto, .my-xl-auto { + margin-top: auto !important + } + .mr-xl-auto, .mx-xl-auto { + margin-right: auto !important + } + .mb-xl-auto, .my-xl-auto { + margin-bottom: auto !important + } + .ml-xl-auto, .mx-xl-auto { + margin-left: auto !important + } +} + +.text-monospace { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", + "Courier New", monospace !important +} + +.text-justify { + text-align: justify !important +} + +.text-wrap { + white-space: normal !important +} + +.text-nowrap { + white-space: nowrap !important +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.text-left { + text-align: left !important +} + +.text-right { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +@media ( min-width :576px) { + .text-sm-left { + text-align: left !important + } + .text-sm-right { + text-align: right !important + } + .text-sm-center { + text-align: center !important + } +} + +@media ( min-width :768px) { + .text-md-left { + text-align: left !important + } + .text-md-right { + text-align: right !important + } + .text-md-center { + text-align: center !important + } +} + +@media ( min-width :992px) { + .text-lg-left { + text-align: left !important + } + .text-lg-right { + text-align: right !important + } + .text-lg-center { + text-align: center !important + } +} + +@media ( min-width :1200px) { + .text-xl-left { + text-align: left !important + } + .text-xl-right { + text-align: right !important + } + .text-xl-center { + text-align: center !important + } +} + +.text-lowercase { + text-transform: lowercase !important +} + +.text-uppercase { + text-transform: uppercase !important +} + +.text-capitalize { + text-transform: capitalize !important +} + +.font-weight-light { + font-weight: 300 !important +} + +.font-weight-lighter { + font-weight: lighter !important +} + +.font-weight-normal { + font-weight: 400 !important +} + +.font-weight-bold { + font-weight: 700 !important +} + +.font-weight-bolder { + font-weight: bolder !important +} + +.font-italic { + font-style: italic !important +} + +.text-white { + color: #fff !important +} + +.text-primary { + color: #446e9b !important +} + +a.text-primary:focus, a.text-primary:hover { + color: #2d4866 !important +} + +.text-secondary { + color: #999 !important +} + +a.text-secondary:focus, a.text-secondary:hover { + color: #737373 !important +} + +.text-success { + color: #3cb521 !important +} + +a.text-success:focus, a.text-success:hover { + color: #277415 !important +} + +.text-info { + color: #3399f3 !important +} + +a.text-info:focus, a.text-info:hover { + color: #0c73cd !important +} + +.text-warning { + color: #d47500 !important +} + +a.text-warning:focus, a.text-warning:hover { + color: #884b00 !important +} + +.text-danger { + color: #cd0200 !important +} + +a.text-danger:focus, a.text-danger:hover { + color: #810100 !important +} + +.text-light { + color: #eee !important +} + +a.text-light:focus, a.text-light:hover { + color: #c8c8c8 !important +} + +.text-dark { + color: #333 !important +} + +a.text-dark:focus, a.text-dark:hover { + color: #0d0d0d !important +} + +.text-body { + color: #777 !important +} + +.text-muted { + color: #777 !important +} + +.text-black-50 { + color: rgba(0, 0, 0, .5) !important +} + +.text-white-50 { + color: rgba(255, 255, 255, .5) !important +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0 +} + +.text-decoration-none { + text-decoration: none !important +} + +.text-break { + word-break: break-word !important; + overflow-wrap: break-word !important +} + +.text-reset { + color: inherit !important +} + +.visible { + visibility: visible !important +} + +.invisible { + visibility: hidden !important +} + +@media print { + *, ::after, ::before { + text-shadow: none !important; + box-shadow: none !important + } + a:not (.btn ){ + text-decoration: underline + } + abbr[title]::after { + content: " (" attr(title) ")" + } + pre { + white-space: pre-wrap !important + } + blockquote, pre { + border: 1px solid #999; + page-break-inside: avoid + } + thead { + display: table-header-group + } + img, tr { + page-break-inside: avoid + } + h2, h3, p { + orphans: 3; + widows: 3 + } + h2, h3 { + page-break-after: avoid + } + @page { + size: a3 + } + body { + min-width: 992px !important + } + .container { + min-width: 992px !important + } + .navbar { + display: none + } + .badge { + border: 1px solid #000 + } + .table { + border-collapse: collapse !important + } + .table td, .table th { + background-color: #fff !important + } + .table-bordered td, .table-bordered th { + border: 1px solid #dee2e6 !important + } + .table-dark { + color: inherit + } + .table-dark tbody+tbody, .table-dark td, .table-dark th, .table-dark thead th + { + border-color: #dee2e6 + } + .table .thead-dark th { + color: inherit; + border-color: #dee2e6 + } +} + +.navbar .nav-link, .navbar .navbar-brand { + text-shadow: -1px -1px 0 rgba(0, 0, 0, .1); + transition: color ease-in-out .2s +} + +.navbar.bg-primary { + background-image: linear-gradient(#6d94bf, #446e9b 50%, #3e648d); + background-repeat: no-repeat; + filter: none; + border: 1px solid #345578 +} + +.navbar.bg-dark { + background-image: linear-gradient(#bfbfbf, #999 50%, #8f8f8f); + background-repeat: no-repeat; + filter: none; + border: 1px solid gray +} + +.navbar.bg-light { + background-image: linear-gradient(white, #eee 50%, #e4e4e4); + background-repeat: no-repeat; + filter: none; + border: 1px solid #d5d5d5 +} + +.navbar.bg-light .nav-link, .navbar.bg-light .navbar-brand { + text-shadow: 1px 1px 0 rgba(255, 255, 255, .1) +} + +.navbar.bg-light .navbar-brand { + color: rgba(0, 0, 0, .4) +} + +.navbar.bg-light .navbar-brand:hover { + color: #3399f3 +} + +.btn { + text-shadow: -1px -1px 0 rgba(0, 0, 0, .1) +} + +.btn-link { + text-shadow: none +} + +.btn-primary { + background-image: linear-gradient(#6d94bf, #446e9b 50%, #3e648d); + background-repeat: no-repeat; + filter: none; + border: 1px solid #345578 +} + +.btn-primary:not (.disabled ):hover { + background-image: linear-gradient(#5f8ab9, #3e648d 50%, #385a7f); + background-repeat: no-repeat; + filter: none; + border: 1px solid #2e4b69 +} + +.btn-secondary { + background-image: linear-gradient(#bfbfbf, #999 50%, #8f8f8f); + background-repeat: no-repeat; + filter: none; + border: 1px solid gray +} + +.btn-secondary:not (.disabled ):hover { + background-image: linear-gradient(#b5b5b5, #8f8f8f 50%, #858585); + background-repeat: no-repeat; + filter: none; + border: 1px solid #757575 +} + +.btn-success { + background-image: linear-gradient(#61dd45, #3cb521 50%, #36a41e); + background-repeat: no-repeat; + filter: none; + border: 1px solid #2e8a19 +} + +.btn-success:not (.disabled ):hover { + background-image: linear-gradient(#52da34, #36a41e 50%, #31921b); + background-repeat: no-repeat; + filter: none; + border: 1px solid #287916 +} + +.btn-info { + background-image: linear-gradient(#7bbdf7, #3399f3 50%, #208ff2); + background-repeat: no-repeat; + filter: none; + border: 1px solid #0e80e6 +} + +.btn-info:not (.disabled ):hover { + background-image: linear-gradient(#68b3f6, #208ff2 50%, #0e86ef); + background-repeat: no-repeat; + filter: none; + border: 1px solid #0c75d2 +} + +.btn-warning { + background-image: linear-gradient(#ff9c22, #d47500 50%, #c06a00); + background-repeat: no-repeat; + filter: none; + border: 1px solid #a15900 +} + +.btn-warning:not (.disabled ):hover { + background-image: linear-gradient(#ff930d, #c06a00 50%, #ab5e00); + background-repeat: no-repeat; + filter: none; + border: 1px solid #8d4e00 +} + +.btn-danger { + background-image: linear-gradient(#ff1d1b, #cd0200 50%, #b90200); + background-repeat: no-repeat; + filter: none; + border: 1px solid #9a0200 +} + +.btn-danger:not (.disabled ):hover { + background-image: linear-gradient(#ff0906, #b90200 50%, #a40200); + background-repeat: no-repeat; + filter: none; + border: 1px solid #860100 +} + +.btn-light { + background-image: linear-gradient(white, #eee 50%, #e4e4e4); + background-repeat: no-repeat; + filter: none; + border: 1px solid #d5d5d5 +} + +.btn-light:not (.disabled ):hover { + background-image: linear-gradient(white, #e4e4e4 50%, #dadada); + background-repeat: no-repeat; + filter: none; + border: 1px solid #cacaca +} + +.btn-dark { + background-image: linear-gradient(#595959, #333 50%, #292929); + background-repeat: no-repeat; + filter: none; + border: 1px solid #1a1a1a +} + +.btn-dark:not (.disabled ):hover { + background-image: linear-gradient(#4f4f4f, #292929 50%, #1f1f1f); + background-repeat: no-repeat; + filter: none; + border: 1px solid #0f0f0f +} + +[class*=btn-outline-] { + text-shadow: none +} + +.badge-secondary { + color: #fff +} + +.card h1, .card h2, .card h3, .card h4, .card h5, .card h6, + .list-group-item h1, .list-group-item h2, .list-group-item h3, + .list-group-item h4, .list-group-item h5, .list-group-item h6 { + color: inherit +} \ No newline at end of file diff --git a/css/bootstrap4-toggle.min.css b/css/bootstrap4-toggle.min.css new file mode 100755 index 0000000..42b1ec7 --- /dev/null +++ b/css/bootstrap4-toggle.min.css @@ -0,0 +1,10 @@ +/*\ +|*| ======================================================================== +|*| Bootstrap Toggle: bootstrap4-toggle.css v3.6.1 +|*| https://gitbrent.github.io/bootstrap4-toggle/ +|*| ======================================================================== +|*| Copyright 2018-2019 Brent Ely +|*| Licensed under MIT +|*| ======================================================================== +\*/ +.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}.toggle{position:relative;overflow:hidden}.toggle.btn.btn-light,.toggle.btn.btn-outline-light{border-color:rgba(0,0,0,.15)}.toggle input[type=checkbox]{display:none}.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}.toggle-group label,.toggle-group span{cursor:pointer}.toggle.off .toggle-group{left:-100%}.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:#fff}.toggle.btn-outline-primary .toggle-handle{background-color:var(--primary);border-color:var(--primary)}.toggle.btn-outline-secondary .toggle-handle{background-color:var(--secondary);border-color:var(--secondary)}.toggle.btn-outline-success .toggle-handle{background-color:var(--success);border-color:var(--success)}.toggle.btn-outline-danger .toggle-handle{background-color:var(--danger);border-color:var(--danger)}.toggle.btn-outline-warning .toggle-handle{background-color:var(--warning);border-color:var(--warning)}.toggle.btn-outline-info .toggle-handle{background-color:var(--info);border-color:var(--info)}.toggle.btn-outline-light .toggle-handle{background-color:var(--light);border-color:var(--light)}.toggle.btn-outline-dark .toggle-handle{background-color:var(--dark);border-color:var(--dark)}.toggle[class*=btn-outline]:hover .toggle-handle{background-color:var(--light);opacity:.5}.toggle.btn{min-width:3.7rem;min-height:2.15rem}.toggle-on.btn{padding-right:1.5rem}.toggle-off.btn{padding-left:1.5rem}.toggle.btn-lg{min-width:5rem;min-height:2.815rem}.toggle-on.btn-lg{padding-right:2rem}.toggle-off.btn-lg{padding-left:2rem}.toggle-handle.btn-lg{width:2.5rem}.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}.toggle-on.btn-sm{padding-right:1rem}.toggle-off.btn-sm{padding-left:1rem}.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}.toggle-on.btn-xs{padding-right:.8rem}.toggle-off.btn-xs{padding-left:.8rem} diff --git a/css/common.css b/css/common.css new file mode 100644 index 0000000..9e723c4 --- /dev/null +++ b/css/common.css @@ -0,0 +1,126 @@ +.navColor { + background: #882929; + color: white; +} + +.userName { + padding-left: 10px; + padding-right: 10px; + border: 1px solid rgba(0, 0, 0, .125); + border-radius: 5px; + background: white; + color: #2E324C; +} + +.userName:hover { + cursor: pointer; + background: rgb(68, 110, 155); + color: white; + border-radius: 5px; +} + +#horiNav { + padding-top: 10px; + border: 1px solid rgba(0, 0, 0, .05); + background: #f8f9fa; +} + +#outputNav { + padding-top: 10px; + border: 1px solid rgba(0, 0, 0, .05); + background: #f8f9fa; +} + +div .card { + background: #f8f9fa; +} + +#main { + background: white; + color: black; +} + .active>.iconimg { + height: 25px; + width: 25px; + margin-right: 10px; + filter: invert(100%); +} + +.iconimg { + height: 25px; + width: 25px; + margin-right: 10px; + filter: invert(15%) sepia(11%) saturate(2467%) hue-rotate(194deg) + brightness(94%) contrast(84%); +} + +.buttonimg { + height: 23px; + width: 23px; + filter: invert(15%) sepia(11%) saturate(2467%) hue-rotate(194deg) + brightness(94%) contrast(84%); +} + +.closeimg { + height: 12px; + width: 12px; + filter: invert(15%) sepia(11%) saturate(2467%) hue-rotate(194deg) + brightness(94%) contrast(84%); + +} + +.closeimg:hover { + cursor:pointer; + +} + +.active>.closeimg { + filter: invert(100%); +} + +.trigimg { + height: 20px; + width: 20px; +} + +.projectLine.collapsed { + background: #D5D6DB; + color: #2E324C; +} + +.projectLine { + background: #2E324C; + color: white; +} + +.projectLine.collapsed:hover { + background: #2E324C; + color: white; +} + + button:hover>.trigimg { + filter: invert(100%); +} + + button[aria-expanded="true"]>.trigimg { + filter: invert(100%); +} + + button:hover>.buttonimg { + filter: invert(100%); +} + +.headerFooter { + background: #2E324C; + color: white; +} + +.outline-btn { + border: 1px solid #999; + border-radius: 3px; +} + +div.filter-option { + border: 1px solid #999; + border-radius: 3px; +} \ No newline at end of file diff --git a/css/loading.css b/css/loading.css new file mode 100644 index 0000000..2c57f1b --- /dev/null +++ b/css/loading.css @@ -0,0 +1,41 @@ +.loader, +.loader:after { + border-radius: 50%; + width: 10em; + height: 10em; +} +.loader { + margin: 60px auto; + font-size: 10px; + position: relative; + text-indent: -9999em; + border-top: 1.1em solid rgba(202,101,64, 0.2); + border-right: 1.1em solid rgba(202,101,64, 0.2); + border-bottom: 1.1em solid rgba(202,101,64, 0.2); + border-left: 1.1em solid #ca6540; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); + -webkit-animation: load8 1.1s infinite linear; + animation: load8 1.1s infinite linear; +} +@-webkit-keyframes load8 { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes load8 { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/css/staticAnalysis.css b/css/staticAnalysis.css new file mode 100755 index 0000000..0042605 --- /dev/null +++ b/css/staticAnalysis.css @@ -0,0 +1,3 @@ +#textareaDiv > .CodeMirror{ + height:auto; +} \ No newline at end of file diff --git a/doc/.buildinfo b/doc/.buildinfo new file mode 100644 index 0000000..131e907 --- /dev/null +++ b/doc/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 423e538f52868c987d0aa6f22d63ed1b +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/ContractAPI.html b/doc/ContractAPI.html new file mode 100644 index 0000000..e953828 --- /dev/null +++ b/doc/ContractAPI.html @@ -0,0 +1,5960 @@ + + + + + + + + + + BDContract SDK — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract SDK

+

除使用可视化的智能合约在线IDE外,用户还可使用WebSocket接口、Http接口、Bash接口来启动和运行合约.

+
+
+

WebSocketSDK下载与安装

+

合约SDK提供javascript版本与java版本的客户端。

+

java客户端的下载链接为:java +sourcejar +可参考java_source下的README.md及测试用例。

+

javascript的下载链接为:js SDK +内置的SM2加密库链接:sm2 SDK

+
+

建立连接

+

建立与节点服务器之间的WebSocket连接.

+
+

参数

+ ++++ + + + + + + + + + + + + + +

字段

url

建立WebSocket的服务器URL. 使用http协议时, +前缀为ws://, +如"ws://localhost:1717/SCIDE/SCExecutor"; +使用https协议时, 前缀为wss://

msgHand +ler

收到服务器WebSocket回复后的回调函数, 用户可自行编写, +也可参考下面提供的示例

+
+
+

请求示例

+
var url = "ws://127.0.0.1:1717/SCIDE/SCExecutor";//与Slave节点建立连接
+//var url = "ws://127.0.0.1:1718/NodeCenterWS";//与Manager节点建立连接
+var msgHandler = function(m){
+  console.log("recmsg:");
+  console.log(m);
+};
+var onOpenHandler=undefined;
+wssocket = createWssocket(url,onOpenHandler,msgHandler);
+
+
+
+
+

返回结果示例

+
{
+  receiveSeg: [Function (anonymous)],
+  isSending: false,
+  sendList: [],
+  monitor: [Function (anonymous)],
+  send: [Function (anonymous)],
+  sendNextSegment: [Function (anonymous)],
+  isOpen: [Function (anonymous)]
+}
+
+
+
+
+
+

ping

+

ping服务器测试

+
+

参数

+ ++++ + + + + + + + + + + +

字段

action

ping

+
+
+

请求示例

+
var request = {};
+request.action = "ping";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+

返回结果示例

+
{
+    "action":"pong"
+}
+
+
+
+
+
+

登录

+

使用Websocket接口调用需要权限的接口时,不论是连接CenterPortal还是NodePortal必须先登录。 +登录的流程有3步:

+
    +
  • 客户端向服务端建立连接,连接建立完成后发送{“action”:“getSessionID”}(可在onOpenHandler中实现)

  • +
  • 服务端收到请求后,会向客户端返回类似{“action”:“onGetSessionID”,“session”:“-4959947809200104526_session”}的结果

  • +
  • 客户端收到onGetSessionID后,会使用本地的公私钥对sessionID进行签名,并调用login接口

  • +
  • 服务端会返回onLogin的结果,data字段返回的是该公钥对应的角色。

  • +
+
+
+
+
+

用户角色划分

+
+

合约节点的角色划分

+

在合约节点(NodePortal.html)中分为NodeManager/ContractProvider/ContractInstanceManager/ContractUser四类角色。

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

角色

说明

NodeManager

该节点的管理者,拥有用户管理、节点配置等权限

ContractProvider

拥有编辑合约、开发合约代码、运行调试等权限

ContractInstanceManager

拥有启、停合约实例、配置合约实例IO等权限

ContractUser

拥有查看合约实例列表、调用合约等权限

Anonymous

匿名用户,可以调用合约,可以申请成为ContractProvider/InstanceManager等角色

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口

说明

角色

changeDumpPeriod

设置备份周期

ContractInstanceManager;

createLedger

创建账本

ContractInstanceManager;

dumpContract

手动备份

ContractInstanceManager;

deleteMemoryFile

删除镜像

ContractInstanceManager;

forkContract

迁移合约

ContractInstanceManager;

getDumpPeriod

获取备份周期

ContractInstanceManager;

killAllContract

停止全部实例

ContractInstanceManager;

killContractProcess

停止某一实例

ContractInstanceManager;

listMemoryFiles

列取某一实例的镜像

ContractInstanceManager;

loadMemory

加载镜像

ContractInstanceManager;

queryContractInstanceDOI

查询合约实例信息

ContractInstanceManager;

rebuildHashIndex

ContractInstanceManager;

setPermission

ContractProvider;ContractInstanceManager;

startContract

启动合约

ContractInstanceManager;

startContractBatched

废弃

ContractInstanceManager;

startContractByYPK

启动合约

ContractInstanceManager;

startContractInTempZips

废弃

ContractInstanceManager;

startContractP2PTrustfully

启动合约(集群模式)

ContractInstanceManager;

updateContract

ContractInstanceManager;

connectTo

连接合约实例输出流

ContractInstanceManager;ContractUser;

countContractLogGroupByAction

ContractInstanceManager;ContractUser;

countContractLogGroupByCategory

ContractInstanceManager;ContractUser;

getLastLog

查询日志

ContractInstanceManager;ContractUser;

getLog

查询日志

ContractInstanceManager;ContractUser;

getLogSize

查询日志

ContractInstanceManager;ContractUser;

listAllContractProcess

ContractInstanceManager;ContractUser;

listContractProcess

查询合约实例列表

ContractInstanceManager;ContractUser;

listLeakContractProcess

ContractInstanceManager;ContractUser;

queryContractLogByDate

ContractInstanceManager;ContractUser;

queryContractLogByKey

ContractInstanceManager;ContractUser;

queryContractLogByOffset

ContractInstanceManager;ContractUser;

queryContractLogDetail

ContractInstanceManager;ContractUser;

queryContractLogSize

ContractInstanceManager;ContractUser;

queryNodeLogByDate

ContractInstanceManager;ContractUser;

queryNodeLogByOffset

ContractInstanceManager;ContractUser;

queryNodeLogSize

ContractInstanceManager;ContractUser;

rebuildContractLogIndex

ContractInstanceManager;ContractUser;

rebuildNodeLogIndex

ContractInstanceManager;ContractUser;

changePublic

ContractProvider;

createFile

新建文件

ContractProvider;

deleteFile

删除文件

ContractProvider;

distributeContract

ContractProvider;

downloadContract

ContractProvider;

downloadContractFromOtherHost

ContractProvider;

generateAnnotationSample

ContractProvider;

generateAppDataAnalysis

ContractProvider;

generateAppDataSource

ContractProvider;

generateBDCoinEventProject

ContractProvider;

generateBDCoinProject

ContractProvider;

generateBiddingExample

ContractProvider;

generateCSVProject

ContractProvider;

generateContractExecutor

ContractProvider;

generateDAC4BDOA

ContractProvider;

generateDAC4BDOA_persist

ContractProvider;

generateDACSample

ContractProvider;

generateEmptyProject

ContractProvider;

generateEventPublisher

ContractProvider;

generateEventSubscriber

ContractProvider;

generateGasExample

ContractProvider;

generateHello

ContractProvider;

generateHttpExample

ContractProvider;

generateIncentives

ContractProvider;

generateJSONExample

ContractProvider;

generateLedgerExample

ContractProvider;

generateLedgerProject

ContractProvider;

generateLicenceManager

ContractProvider;

generateLoggerExample

ContractProvider;

generateMySQLExample

ContractProvider;

generateMySQLProject

ContractProvider;

generatePostgreSQLSample

ContractProvider;

generateReadme

ContractProvider;

generateRenderSample

ContractProvider;

generateRocksDBSample

ContractProvider;

generateSM2Example

ContractProvider;

generateStaticResource

ContractProvider;

generateTFLinux

ContractProvider;

generategenerateTFMac

ContractProvider;

getProject

ContractProvider;

getTemplateList

ContractProvider;

importContractInstanceCodeByDOI

ContractProvider;

listFile

ContractProvider;

listProject

ContractProvider;

listProjectPermission

ContractProvider;

listProjects

ContractProvider;

renameFile

ContractProvider;

saveFile

ContractProvider;

startContractAsDebug

ContractProvider;

uploadFile

ContractProvider;

compile

ContractProvider;ContractInstanceManager;

evaluates

ContractProvider;ContractInstanceManager;

executeContractP2PTrustfully

ContractProvider;ContractInstanceManager;

getCodeByID

查询代码

ContractProvider;ContractInstanceManager;

getControlFlowByFileName

ContractProvider;ContractInstanceManager;

getGasValue

ContractProvider;ContractInstanceManager;

listCompiledFiles

ContractProvider;ContractInstanceManager;

queryContractResourceInfo

ContractProvider;ContractInstanceManager;

queryFreeResourceInfo

ContractProvider;ContractInstanceManager;

staticVerifyContract

ContractProvider;ContractInstanceManager;

writeDyjs

ContractProvider;ContractInstanceManager;

authNodeRole

授权角色

NodeManager;

changeBDledger

修改账本配置

NodeManager;

changeIpPort

NodeManager;

changeNodeCenter

修改集群地址

NodeManager;

changeNodeName

NodeManager;

changeIpPort

NodeManager;

changeDOIPConfig

NodeManager;

changeYJSPath

NodeManager;

countNodeLogGroupByCategory

NodeManager;

countRole

NodeManager;

deleteRole

NodeManager;

downloadUUID

废弃

NodeManager;

getEncodedUUID

废弃

NodeManager;

getPeerID

NodeManager;

listAllAuthRole

NodeManager;

listNodeInfos

NodeManager;

listUnAuthRole

NodeManager;

loadConfig

NodeManager;

loadNodeConfig

NodeManager;

lockEdit

NodeManager;

unlockEdit

NodeManager;

updateConfig

NodeManager;

uploadLicence

NodeManager;

applyNodeRole

申请角色

任意角色

executeContract

调用合约

任意角色

getConnCount

任意角色

getHashAbstractLocally

任意角色

getHashLocally

任意角色

getNodeRoleDeprecated

查询当前角色

任意角色

getSessionID

任意角色

listAdapters

任意角色

listTheContractProcess

任意角色

login

登录

任意角色

longStr

任意角色

ping

任意角色

queryDataByHash

任意角色

queryDataByHashLocally

任意角色

queryHashByOffset

任意角色

queryHashByRequestID

任意角色

queryHashSize

任意角色

queryLedgers

任意角色

queryRole

任意角色

queryTransactionByHash

任意角色

sendTransaction

任意角色

setLogStage

任意角色

+
+
+

合约准入中心角色划分

+

共分为两类角色:CenterManager和NodeManager。其中,CenterManager拥有对集群设置的权限。 +NodeManager可以增加、删除节点等操作。

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

接口

说明

角色

authNodeManager

CenterManager;

countActionLogByCategory

CenterManager;

countCMLogByCategory

CenterManager;

delete

CenterManager;

listAllUsers

CenterManager;

listApplyList

CenterManager;

listLicence

CenterManager;

queryActionLog

CenterManager;

queryCMLog

CenterManager;

updateLicence

CenterManager;

addNode

CenterManager;NodeManager;

changeNCFile

CenterManager;NodeManager;

changeOtherNC

CenterManager;NodeManager;

createTrustUnit

创建可信集群

CenterManager;NodeManager;

deleteTrustUnit

CenterManager;NodeManager;

getNCFile

CenterManager;NodeManager;

getNodeTrustUnits

CenterManager;NodeManager;

getOtherNC

CenterManager;NodeManager;

listContractProcess

CenterManager;NodeManager;

listMultiPointContractProcess

CenterManager;NodeManager;

listNodes

CenterManager;NodeManager;

listTrustUnits

CenterManager;NodeManager;

queryUserStat

CenterManager;NodeManager;

stopMultiPointContractProcess

CenterManager;NodeManager;

applyRole

NodeManager;

executeContract

调用合约

任意角色

executeContractTrustfully

任意角色

getManagerPubkey

任意角色

getNodeRole

任意角色

getNodeSessionID

任意角色

getRole

任意角色

getSessionID

任意角色

login

登录

任意角色

+
+
+
+
+

合约节点Http接口

+

http://xxx.xxx.xxx.xxx:1717/SCIDE/SCManager为提供Http接口服务的服务器 +URL(xxx.xxx.xxx.xxx:1717为BDWare SCIDE运行的IP和端口号) , +用户可通过在URL后附加字段参数, 完成以下功能. +http://xxx.xxx.xxx.xxx:18000/SCIDE/SCManager +为提供Http接口服务的服务器

+

URL(xxx.xxx.xxx.xxx:1717 为BDWare +SCIDE运行的IP和端口号),用户可通过在URL后附加字段参数,完成以下功能:

+
+

用户管理类

+
+

ping

+

ping服务器测试

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

ping

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=ping
+
+
+
+
+
返回结果示例
+
{"data":"pong"}
+
+
+
+
+
+
+

合约代码管理类

+
+

下载合约项目

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

downloadContract

projectName

合约项目名

isPrivate

是否在私有目录下

pubKey

用户公钥

timestamp

时间戳

sign

签名

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=downloadContract&projectName=BDCoin&isPrivate=false&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3
+8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275
+
+
+
+
+
+

上传文件

+
+
方法
+

POST

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

path

文件上传路径

fileName

待上传文件名

isPrivate

是否在私有目录下

order

第几个数据包

count

数据包总数

timestamp

时间戳

sign

签名

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/Upload?path=/TEST/TEST.yjs&fileName=WechatIMG15.jpeg&isPrivate=true&order=0&count=3&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05&sign=dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275
+
+
+
+
+
返回结果示例
+
{"status":"true","data":"success"}
+
+
+
+
+
+

保存合约脚本

+

向服务器发送请求, 向服务器本地保存合约脚本内容.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

writeDyjs

target

合约脚本文件名

content

合约脚本内容

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=writeDyjs&target=testyjs.yjs&content=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onWriteDyjs",
+    "data": "success"
+}
+
+
+

后续用户可启动并调用该合约.

+
+
+
+
+

合约实例管理类

+
+

查询合约进程

+

向服务器发送请求, 查询服务器上已经启动的所有合约进程.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listContractProcess

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=listContractProcess
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onListContractProcess",
+    "data": "[\n  {\n    \"id\": \"-562752842\",\n    \"name\": \"shortc\",\n    \"port\": \"1626\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  }\n]"
+}
+
+
+
+
+
+

启动合约

+

向服务器发送请求, 启动某个合约.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

startContract

script

合约脚本内容, 需进行进行URIEncode

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContract&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D
+
+
+
+
+
返回结果示例
+
{
+    "data": "{\"status\":\"Success\",\"result\":\"\"}",
+    "action": "onStartContract",
+    "cid": "-562752842",
+    "executeTime": 1187
+}
+
+
+
+
+
+

调用合约

+

向服务器发送请求, 调用某个合约.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

executeContract

contractID

合约ID

withDynamicAnalysis

true/false 是否进行动态分析

operation

调用合约的方法名

arg

调用合约的参数

pubkey

可选,调用者公钥

signature

可选,签名

+

其中pubkey为sm2的公钥,计算方式如下:

+
//sm2 可从sm2.js中加载获得。
+signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey);
+
+
+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=executeContract&contractID=-620602333&operation=main&arg=hhh
+
+
+
+
+
返回结果示例
+
{
+    "data": "{\"status\":\"Success\",\"result\":\"3\"}",
+    "action": "onExecuteResult",
+    "executeTime": "13"
+}
+
+
+
+
+
+

批量启动合约

+

向服务器发送请求, 启动服务器中保存有合约脚本的一系列合约.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

startContractBatched

fileList

合约脚本文件列表(Json数组,URLEncode)

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContractBatched&fileList=%5B%20%22EventPuber.yjs%22%2C%20%22EventSuber.yjs%22%2C%20%22LicenceManager.yjs%22%20%5D
+
+
+
+
+
返回结果示例
+
{"EventPuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","LicenceManager.yjs":"{\"status\":\"Success\",\"result\":\"\"}","EventSuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","action":"onStartContract"}
+
+
+
+
+
+

启动Zip包合约

+

向服务器发送请求, 启动服务器中包装为zip格式的合约.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

startContractInTempZips

owner

调用者公钥

path

zip合约(路径及)文件名

signature

调用者签名

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContractInTempZips&owner=0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55&path=traceTest.zip&signature=650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%2C72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2
+
+
+
+
+
返回结果示例
+
{"data":"verify failed","action":"onStartContract"}
+
+
+
+
+
+

获取合约代码

+

向服务器发送请求, 获取某个ID合约的脚本代码.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

getCodeByID

contractID

合约ID

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=getCodeByID&contractID=814046805
+
+
+
+
+
返回结果示例
+
{"status":true,"action":"onCodeResult","data":"@LogType(\"Arg\")\ncontract EventSuberAtCHQ{\n\t\n  \texport function init(arg){\n\t\tvar result \u003d YancloudUtil.subscribe(\"EventPuberAt3966\",\"abc\",handler);\n       // print(\"Handler:\"+handler);\n  \t \n  \t\treturn result;\n\t}\n  \texport function handler(e){\n        var ret \u003d \"ReceiveEvent:\";\n\t\tret+\u003d\"\\n\";\n      \tprint(ret);\n      \tret+\u003dYancloudUtil.executeContract(\"EventPuberAt3966\",\"notify\",\"success\");\n      \tprint(ret);\n        return ret;\n\t}\n}\n"}
+
+
+
+
+
+

保存合约状态

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

dumpContract

contractID

合约ID 或 合约Name=

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/SCManager?action=dumpContract&contractID=counter&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83
+
+
+
+
+
返回结果示例
+
{"data":"success","size":"3.76 KB","time":"0.03s"}
+
+
+
+
+
+

获取合约内存文件列表

+

向服务器发送请求, 获取某子文件夹中的所有内存文件列表.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

listMemoryFiles

contractID

合约Id 或 合约Name

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/SCManager?action=listMemoryFiles&contractID=-247468535&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b
+
+
+
+
+
返回结果示例
+
{"data":["2020-09-23.18:40:38","2020-09-24.16:03:41","2020-09-24.16:58:39","2020-09-24.18:25:47","2020-09-24.18:32:37","2020-09-24.20:54:41","2020-09-24.20:57:39","2020-09-24.21:31:07","2020-09-24.21:32:09","2020-09-24.21:36:11","2020-09-28.15:29:15","2020-09-28.20:28:29","2020-09-28.20:39:46","2020-09-28.21:45:31","2020-09-28.21:49:18","2020-09-28.22:27:34","2020-09-28.22:31:09","2020-09-28.22:32:49","2020-10-07.16:51:06","2020-10-07.16:51:23","2020-10-25.21:09:10","2020-12-14.19:06:53","2021-02-02.10:28:56","2021-02-02.10:31:13"],"action":"onListMemoryFiles"}
+
+
+
+
+
+

停止合约

+

向服务器发送请求, 停止某个合约.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

killContractProcess

id

合约ID

*requestID

请求ID, String类型

+

*表示可选参数

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=killContractProcess&id=-1759263594
+
+
+
+
+
返回结果示例
+
{"status":false,"action":"onListContractProcess","data":"[\n  {\n    \"id\": \"-65051856\",\n    \"name\": \"EventSuber\",\n    \"port\": \"1631\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"814046805\",\n    \"name\": \"EventSuberAtCHQ\",\n    \"port\": \"1630\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"2023975189\",\n    \"name\": \"LicenceService\",\n    \"port\": \"1632\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"-620602333\",\n    \"name\": \"shortc\",\n    \"port\": \"1627\",\n    \"times\": \"0 \",\n    \"traffic\": \"0.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  }\n]"}
+
+
+
+
+
+

停止所有合约

+

向服务器发送请求, 停止服务器上启动的所有合约.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

killAllContract

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=killAllContract
+
+
+
+
+
返回结果示例
+
{"status":false,"action":"onKillAllContract","data":"Kill:7357,7541,7548,7555,7584,7585,7591,7598,7609,7612,8440,8442,8444,8521,"}
+
+
+
+
+
+

静态分析合约

+

向服务器发送请求, 静态分析合约脚本.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

staticVerifyContract

contractid

合约ID

script

请求ID, String类型

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=staticVerifyContract&contractid=943728900&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D&path=static.yjs
+
+
+
+
+
返回结果示例
+
{"data":"{\"status\":\"Success\",\"result\":\"{\\\"main\\\":\\\"Ret:arg \\\"}\"}","action":"onExecuteResult","cid":"943728900","executeTime":54}
+
+
+
+
+
+

获取合约静态分析流

+

向服务器发送请求, 获取某个合约的静态分析Control Flow.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

getControlFlowByFileName

path

合约ID

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=getControlFlowByFileName&path=EventSuber.yjs
+
+
+
+
+
返回结果示例
+
{"init":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","aload 4","invokedynamic dyn:getProp|getElem|getMethod:YancloudUtil (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B3","stmts":["dup","invokedynamic dyn:getMethod|getProp|getElem:subscribe (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B4","stmts":["swap","ldc XiaomiSmartHomeAtPKU","ldc onAirPurifierModeChange","aload 4","invokedynamic dyn:getProp|getElem|getMethod:handler (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B5","stmts":["invokedynamic dyn:call:\\\u003dYancloudUtil\\,subscribe (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B6","stmts":["\u003dL3\u003d","astore 5"],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B7","stmts":["\u003dL4\u003d","aload 5","areturn"],"original":"  \t\treturn result;"},{"type":"Continuous","name":"B8","stmts":["\u003dL5\u003d"],"original":"  \t\treturn result;"},{"type":"Continuous","name":"B9","stmts":["\u003dL6\u003d"],"original":"  \t\treturn result;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B9","label":{"label":"e"}}]},"handler":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","ldc ReceiveEvent:","aload 2","invokedynamic dyn:getProp|getElem|getMethod:content (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B3","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B4","stmts":["ldc  ","invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B5","stmts":["aload 2","invokedynamic dyn:getProp|getElem|getMethod:type (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B6","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B7","stmts":["\u003dL3\u003d","astore 5"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B8","stmts":["\u003dL4\u003d","aload 4","invokedynamic dyn:getMethod|getProp|getElem:print (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B9","stmts":["getstatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime UNDEFINED Lwrp/jdk/nashorn/internal/runtime/Undefined;","aload 5","invokedynamic dyn:call:print (Ljava/lang/Object;Lwrp/jdk/nashorn/internal/runtime/Undefined;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B10","stmts":["pop"],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B11","stmts":["\u003dL5\u003d","aload 5","areturn"],"original":"        return ret;"},{"type":"Continuous","name":"B12","stmts":["\u003dL6\u003d"],"original":"        return ret;"},{"type":"Continuous","name":"B13","stmts":["\u003dL7\u003d"],"original":"        return ret;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B8","label":{"label":"e"}},{"from":"B8","to":"B9","label":{"label":"e"}},{"from":"B9","to":"B10","label":{"label":"e"}},{"from":"B10","to":"B11","label":{"label":"e"}},{"from":"B11","to":"B13","label":{"label":"e"}}]}}
+
+
+
+
+
+
+

日志查看类

+
+

合约日志-查询数量

+
+
方法
+

GET

+

contractName为空或是不传入时,则为查询全部合约的条数

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryContractLogSize

contractName

字符串,非必须,合约名称

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogSize&contractName=NanningDataSource
+
+
+
+
+
返回结果示例
+
{
+    "size": 12,
+    "action": "onQueryContractLogSize",
+    "status": "success"
+}
+
+
+
+
+
+

合约日志-根据日期查询

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

queryContractLogByDate

start

long,必须,起始时间

end

long,非必须,若无end,默认为当前时间

contractName

字符串,非必须,合约名称

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByDate&start=1597296300272&end=1597296305747
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getMainFrame",
+            "costTime": "2493",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296300272,
+            "key": "-8590335427581967208"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "732",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296301030,
+            "key": "849660532962309239"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4580",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305745,
+            "key": "-8003529429500512736"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4551",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305746,
+            "key": "7604666709899222357"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305751,
+            "key": "-7561786202695627022"
+        }
+    ],
+    "action": "onQueryRecentContractLog"
+}
+
+
+
+
+
+

合约日志-根据偏移量查询

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

queryContractLogByOffset

count

long,必须,获取日志条数

offset

long,非必须,若无offset,默认返回最新count条

contractName

字符串,非必须,合约名称

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByOffset&count=5&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305842,
+            "key": "-2390672423847654148"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "isOwner",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305868,
+            "key": "6056586201629372511"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getApplyList",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305893,
+            "key": "3882409580676458151"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getAcceptList",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305908,
+            "key": "-3437513873417136535"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "analysisByIndustry",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02",
+            "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}",
+            "date": 1597296314654,
+            "key": "203156239086062402"
+        }
+    ],
+    "action": "onQueryRecentContractLog"
+}
+
+
+
+
+
+

合约日志-根据key查询

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryContractLogByKey

key

long,必须,该日志对应的key

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByKey&key=203156239086062402
+
+
+
+
+
返回结果
+
{
+    "data": {
+        "action": "executeContract",
+        "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+        "contractID": "-1382208250",
+        "contractName": "NanningDataSource",
+        "function": "analysisByIndustry",
+        "costTime": "6",
+        "totalGas": "0",
+        "executionGas": "0",
+        "extraGas": "0",
+        "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02",
+        "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}",
+        "date": 1597296314654
+    },
+    "action": "onQueryContractLogByKey"
+}
+
+
+
+
+
+

合约日志-按时间段统计调用次数

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

字段

action

countContractLogGroupByCategory

start

long,必须,起始时间

end

非必须,终止时间,默认为当前

interval

long,非必须,统计间隔

category

非必须,合约名称以逗号连接,不传入时统计全部合约调用情况

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=countContractLogGroupByCategory&start=1596758400000&interval=86400000
+
+
+
+
+
返回结果
+
{
+    "start": 1596758400000,
+    "interval": 86400000,
+    "action": "onCountContractLogGroupByCategory",
+    "data": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        43,
+        14
+    ]
+}
+
+
+
+
+
+

账本日志-查询数量

+

查询通过本节点去账本上记录的日志数量

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryHashSize

contractName

非必须,合约名称

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashSize&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "count": "2",
+    "action": "onQueryHashSize"
+}
+
+
+
+
+
+

账本日志-根据偏移量查询

+

查询x条通过本节点去账本上记录的日志的哈希列表

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

queryHashByOffset

count

整数,必须,表示条数

offset

整数,非必须,表示偏移量,不传入offset则默认返回最新count条

contractName

字符串,非必须,表示合约名称

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashByOffset&count=1&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "hash": "3a6c60621907146b77146c1f2d48700e47520173",
+            "date": 1597296314658
+        }
+    ],
+    "action": "onQueryHash",
+    "status": "success"
+}
+
+
+
+
+
+

账本日志-根据hash查询详情

+

根据hash来查询日志内容

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryDataByHash

hash

字符串,可通过queryHashByOffset

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryDataByHash&count=1&contractName=NanningDataSource&hash=3a6c60621907146b77146c1f2d48700e47520173
+
+
+
+
+
返回结果
+
{
+    "from": "0x3034643139323433323966373263656431343866",
+    "to": "0x65786563757465436f6e74726163740000000000",
+    "data": "1597296314655 --> {\"extraGas\":\"0\",\"totalGas\":\"0\",\"executionGas\":\"0\",\"signature\":\"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02\",\"costTime\":\"6\",\"arg\":\" {\\\\\\\"year\\\\\\\":2018,\\\\\\\"category\\\\\\\":\\\\\\\"工业\\\\\\\",\\\\\\\"indexType\\\\\\\":\\\\\\\"营业额\\\\\\\"}\",\"contractID\":\"-1382208250\",\"action\":\"analysisByIndustry\",\"pubKey\":\"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd\"}",
+    "requestID": "1597296314629_6067",
+    "action": "onQueryDataByHash"
+}
+
+
+
+
+
+

账本日志-根据requestID查询Hash

+

根据requestID来查询日志内容,需由开发者保证requestID的唯一性

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryHashByRequestID

requestID

字符串,在发起调用时生成

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=queryHashByRequestID&requestID=0987654321ab
+
+
+
+
+
+

节点日志-查询数量

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryNodeLogSize

category

非必须,不传入时查询全部情况

+

其中包括:ping、startContract、saveFile等。

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize&category=login
+
+
+
+
+
返回结果
+
{
+    "size": 177,
+    "action": "onQueryNodeLogSize",
+    "status": "success"
+}
+
+
+
+
+
+

节点日志-按日期查询

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

queryNodeLogByDate

start

long,必须,起始日期

end

long,非必须

category

非必须,不传入时查询全部情况

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1597376006441
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1596758400000&category=login
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "listAllAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006438,
+            "key": "387355870552374748"
+        },
+        {
+            "action": "listUnAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006441,
+            "key": "4772693258708933626"
+        },
+        {
+            "action": "countRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006444,
+            "key": "-6425375229108830572"
+        },
+        {
+            "action": "loadNodeConfig",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006448,
+            "key": "-6602401010405792959"
+        },
+        {
+            "action": "getPeerID",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006449,
+            "key": "-7006776427870311552"
+        }
+    ],
+    "action": "onQueryNodeLogByDate"
+}
+
+
+
+
+
+

节点日志-按偏移量查询

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

queryNodeLogByOffset

count

long,必须,获取日志条数

offset

long,非必须,若无offset,默认返回最新count条

contractName

字符串,非必须,合约名称

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByOffset&count=5
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "listAllAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006438,
+            "key": "387355870552374748"
+        },
+        {
+            "action": "listUnAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006441,
+            "key": "4772693258708933626"
+        },
+        {
+            "action": "countRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006444,
+            "key": "-6425375229108830572"
+        },
+        {
+            "action": "loadNodeConfig",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006448,
+            "key": "-6602401010405792959"
+        },
+        {
+            "action": "getPeerID",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006449,
+            "key": "-7006776427870311552"
+        }
+    ],
+    "action": "onQueryNodeLogByOffset"
+}
+
+
+
+
+
+

节点日志-按时间段统计调用次数

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

字段

action

countLogGroupByCategory

start

long,必须,起始时间

end

非必须,终止时间,默认为当前

interval

long,非必须,统计间隔

category

非必须,action以逗号连接,不传入时统计全部调用情况

+

其中,category中的action为NodePortal的接口的action集合。 +包括:ping、startContract、saveFile等。

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000&category=ping,startContract
+
+
+
+
+
返回结果
+
{
+    "start": 1596758400000,
+    "interval": 86400000,
+    "action": "onCountNodeLogGroupByCategory",
+    "data": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        912,
+        761
+    ]
+}
+
+
+
+
+
+

输出历史记录日志

+

向服务器发送请求, 获取节点服务器上合约的TimeTravel日志.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

printTimeTravelLog

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=printTimeTravelLog
+
+
+
+
+
返回结果示例
+
{"status":false,"data":"[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa_1572335939893.dyjs\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n"}
+
+
+
+
+
+

输出节点转移日志

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
方法
+

GET

+
+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

printTransferLog

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=printTransferLog
+
+
+
+
+
返回结果示例
+
{"status":false,"data":""}
+
+
+
+
+
+
+

模板生成类

+
+
+
+
+

合约节点WebSocket接口

+
+

用户管理类

+
+

获取Session

+

登录前获取session以便进行签名。

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

getSessionID

+
+
+
请求示例
+
var req = {};
+req.action = "getSessionID";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action": "onSessionID",
+    "session": "9782323_session"
+}
+
+
+
+
+
+

用户登录

+

用户进行公私钥身份验证

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

login

+
+
+
请求示例
+
var loginParam = {};
+loginParam.pubKey = global.sm2Key.publicKey;
+loginParam.signature = sm2.doSignature(global.session,
+            global.sm2Key.privateKey);
+loginParam.action = "login";
+wssocket.send(JSON.stringify(loginParam));
+
+
+
+
+
返回结果
+
{
+    "action": "onLogin",
+    "data": "NodeManager,ContractProvider"
+}
+
+
+
+
+
+

申请角色

+

在节点管理员界面申请可以申请称为合约管理员(ContractInstanceManager)、合约使用者(ContractUser)、合约提供者(ContractProvider)

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

applyNodeRole

role

申请角色名称

+
+
+
请求示例
+
var param = {};
+param.action = "applyNodeRole";
+param.role = "ContractUser";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onApplyRole",
+    "data": "success"
+}
+
+{
+    "action":"onApplyRole",
+    "data":"already has!"
+}
+
+
+
+
+
+

授权角色

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

authNodeRole

isAccept

bool类型,表示否授权

pubKey

授权用户公钥

+
+
+
请求示例
+
var param = {};
+param.action = "authNodeRole";
+param.isAccept = true;
+param.pubKey = "xxxxx";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onAuthNodeRole",
+    "data": "success"
+}
+
+
+
+
+
+

删除用户角色

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

deleteRole

role

删除角色名称

+
+
+
请求示例
+
var deleteInfo = {};
+deleteInfo.pubKey = global.authorizedUsers.[publicKey];
+deleteInfo.action = "deleteRole";
+deleteInfo.role="ContractUser";
+wssocket.send(JSON.stringify(deleteInfo));
+
+
+
+
+
返回结果
+
{
+    "action": "onDeleteRole",
+    "data": "success"
+}
+
+
+
+
+
+

查看授权用户列表

+

查看准入管理员当前组网中已经授权的节点管理员

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listAllAuthRole

+
+
+
请求示例
+
var param = {};
+param.action = "listAllAuthRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onListAllAuthRole",
+    "data":
+    {
+        "kv":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab",
+              "value":"NodeManager,ContractProvider,ContractUser,ContractInstanceManager"}],
+        "time":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab",
+                "value":"1617178709933"}]
+    }
+}
+
+
+
+
+
+

查看申请用户列表

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listUnAuthRole

+
+
+
请求示例
+
var param = {};
+param.action = "listUnAuthRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onListUnAuthRole",
+     "kv": [{
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": "ContractProvider,ContractUser"
+    }],
+    "time": [{
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": "1587398989914"
+    }]
+}
+
+
+
+
+
参数(删除)
+ ++++ + + + + + + + + + + +

字段

action

queryUserStat

+
+
+
请求示例
+
var param = {};
+param.action = "queryUserStat";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onQueryUserStat",
+    "userListCount": 3,
+    "applyListCount":0
+}
+
+
+
+
+
+
+

合约代码管理类

+
+

获取公共合约文件列表

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listProjects

+
+
+
请求示例
+
var request = {};
+request.action = "listProjects";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\",\"BiddingExample\",\"ContractExecutor\"]",
+    "executeTime":0,
+    "isPrivate":false
+}
+
+
+
+
+
+

获取私有合约文件列表

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

listProjects

pubKey

该用户的公钥

isPrivate

true

+
+
+
请求示例
+
var request = {};
+request.action = "listProjects";
+request.pubKey = "global.sm2.publicKey";
+request.isPrivate=true;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+

获取合约实例

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listContractProcess

+
+
+
请求示例
+
var request = {};
+request.action = "listContractProcess";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onListContractProcess",
+    "data":"[{\"id\": \"1658407837\",\"name\": \"BDCoin\",\"port\": \"1617\"}]"
+}
+
+
+
+
+
+

启动合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + +

字段

action

startContract

owner

pubkey

requestID

当前时间

script

脚本内容

signature

签名

+
+
+
请求示例
+
request.action = "startContract";
+request.owner = global.sm2Key.publicKey;
+request.requestID = new Date().getTime() + "";
+request.script = global.projectScript;
+request.signature = sm2.doSignature("Algorithm|" + request.script + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey);
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":\"\",\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}",
+    "action":"onStartContract",
+    "cid":"-506393888",
+    "executeTime":2496,
+    "responseID":"1617206735696"
+}
+
+
+
+
+
+

启动可信集群合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

startContractP2PTrustfully

owner

pubkey

isPrivate

当前时间

path

脚本所在路径

signature

签名

peersID

可信执行集群中的节点peerID组成的数组

+
+
+
请求示例
+
var request = {};
+request.action = "startContractP2PTrustfully";
+request.peersID = ["3r729hf2ehf982","sjdfiwoehfwoi34","wnfnwoeifnwenef"];
+var project = "JsonTest";
+request.path = "/" + project + "/mainfest.json";
+request.isPrivate = false;
+request.signature = sm2.doSignature("Trusted|" + request.path + "|"
++ global.sm2Key.publicKey, global.sm2Key.privateKey);  //合约的签名
+request.resultcheck = $("#resultcheck")[0].value;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"status\":\"Success\",\"result\":\"\"}",
+    "action":"onStartContractP2PTrustfully",
+    "cid":"-1543583350",
+    "executeTime":1544
+}
+
+
+
+
+
+

分发合约项目

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

distributeContract

peersID

集群中节点peer

projectName

合约名

isPrivate

是否在私有目录

sponsorPeerID

发起者ID

signature

签名

+
+
+
请求示例
+
request.action = "distributeContract";
+request.peersID = peersID;
+request.projectName = global.projects[global.lastClickedProjectId];
+request.isPrivate = $("#privateDir-tab").hasClass("active");
+request.sponsorPeerID = global.peerID;
+request.signature = sm2.doSignature("DistributeContract|" + request.projectName + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey);
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onDistributeContract",
+    "progress":"100.00%"
+}
+
+
+
+
+
+

终止合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

killContractProcess

id

合约id

requestID

请求ID

+
+
+
请求示例
+
request.action = "killContractProcess";
+request.id = contractid;
+request.requestID = new Date().getTime() + "";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data": "ContractHandler: exit in 3 seconds!",
+    "action": "onOutputStream"
+}
+
+
+
+
+
+

终止所有合约

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

killAllContract

+
+
+
请求示例
+
request.action = "killAllContract";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onKillAllContract",
+    "data":"Kill:7241,7245,"
+}
+
+
+
+
+
+

静态分析合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

staticVerifyContract

owner

用户私钥

isPartial

是否是部分

contractid

contractid

script

脚本内容

path

合约文件名

+
+
+
请求示例
+
request.action = "staticVerifyContract";
+request.owner = global.sm2Key.privateKey
+request.isPartial = false;
+request.contractid = contractid;
+request.script = global.projectScript;
+request.path = global.projectName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":{\"hello\":\"Ret:\"},\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}",
+    "action":"onStaticVerifyResult",
+    "cid":"verify",
+    "executeTime":83
+}
+
+
+
+
+
+

删除合约

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

deleteFile

file

fileName

+
+
+
请求示例
+
request.action = "deleteFile";
+request.file = fileName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onDeleteFile",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

私有合约传至公共目录

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

changePublic

pubkey

用户公钥

fileName

fileName

+
+
+
请求示例
+
request.action = "changePublic";
+request.pubkey = pubkey;
+request.fileName = fileName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onChangePublic",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

上传合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

UploadFile

isAppend

false

fileName

fileName

path

path

isPrivate

true/false

content

fileContent(base64编码)

+
+
+
请求示例
+
request.action = "uploadFile";
+request.isAppend = false;
+request.fileName = "test1.yjs";
+request.path = "test1";
+text="Y29udHJhY3QgdGVzdDF7CglleHBvcnQgZnVuY3Rpb24gaGVsbG8oYXJnKXsgCiAgICAgICAgcmV0dXJuICJ3b3JsZCI7ICAKICAgIH0gICAKfQ=="
+request.content = text;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onUploadFile",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

编译合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

compile

path

string, 待编译的项目名称

privateTab

bool, 是否为私有目录的项目

+
+
+
请求示例
+
var req = {"action":"compile","path":"Hello","privateTab":true}
+
+
+
+
+
返回结果
+
{"result":"Hello_2020-08-17-09:09:40.ypk","action":"onCompile"}
+
+
+
+
+
+

锁定私有目录

+

锁定某个用户的的私有目录编辑功能

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

lockEdit

pubKey

string, 要被锁定的公钥

+
+
+
请求示例
+
var req = {};
+req.action = "lockEdit";
+req.pubKey = "xxxxxx";
+wssocket.send(JSON.stringify(req));
+
+
+
{
+    "action":"onLockEdit",
+    "status":"success",
+    "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1"
+}
+
+
+
+
+
+

解锁私有目录

+

解锁某个用户的的私有目录编辑功能

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

unLockEdit

pubKey

string, 要被锁定的公钥

+
+
+
请求示例
+
var req = {};
+req.action = unlockEdit;
+req.pubKey = "xxxxxx";
+wssocket.send(JSON.stringify(req));
+
+
+
{
+    "action":"onUnlockEdit",
+    "status":"success",
+    "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1"
+}
+
+
+
+
+
+
+

合约实例管理类

+
+

查询合约进程

+

向服务器发送请求, 查询服务器上已经启动的所有合约进程.

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listContractProcess

+
+
+
请求示例
+
var request = {};
+request.action = "listContractProcess";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onListContractProcess",
+    "data": "[...]"
+}
+
+
+
+
+
+

调用合约

+

向服务器发送请求, 调用某个合约.

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

executeContract

contractID

合约ID

withDynamicAnalysis

true/false 是否进行动态分析,可选

operation

调用合约的方法名

arg

调用合约的参数

pubkey

调用者公钥,可选

signature

调用者签名 ,可选

+

*表示可选参数

+
//sm2 可从sm2.js中加载获得。
+signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey);
+
+
+
+
+
请求示例
+
var request = {};
+request.action = "executeContract";
+request.contractID = "2073401446";
+request.operation = "main";
+request.arg = "hhhhh";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "needSeq":false,
+    "seq":0,
+    "status":"Success",
+    "result":"world",
+    "isInsnLimit":false,
+    "totalGas":0,
+    "executionGas":0,
+    "extraGas":0,
+    "size":0,
+    "eventRelated":false,
+    "responseID":"1617211077264_223",
+    "action":"onExecuteResult",
+    "executeTime":"5"
+}
+
+
+
+
+
+

输出历史记录日志(删除)

+

向服务器发送请求, 获取节点服务器上合约的TimeTravel日志.

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

printTimeTravelLog

+
+
+
请求示例
+
var request = {};
+request.action = "printTimeTravelLog";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "data": "[CMActions] dumpContract :…t/contractExamples/memoryDumps/LicenceManager\n"
+}
+
+
+
+
+
+

输出节点转移日志(删除)

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

printTransferLog

+
+
+
请求示例
+
var request = {};
+request.action = "printTransferLog";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
 {
+    "status": false,
+    "data": ""
+}
+
+
+
+
+
+

合约状态迁移

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

loadMemory

contractName

合约名称

memoryFile

合约文件名称

+
+
+
请求示例
+
var request = {};
+request.action = "loadMemory";
+request.contractName = "JsonContract";
+request.memoryFile = "2020-03-17.20/42/55";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "data":"success",
+    "size":"0.00 B",
+    "action":"onTransferTo",
+    "time":"0.01s"
+}
+
+
+
+
+
+
+

日志查看类

+
+

查看本地近n日节点日志(删除)

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

listLocalNodeLog

date

当前时间

+
+
+
请求示例
+
request.action = "listLocalNodeLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+   "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]"
+}
+
+
+
+
+
+

查看本地近n日合约日志(删除)

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

listLocalContractLog

date

当前时间

+
+
+
请求示例
+
request.action = "listLocalContractLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]"
+}
+
+
+
+
+
+
+

节点配置类

+
+

获取节点配置信息

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

loadNodeConfig

+
+
+
请求示例
+
var param = {};
+param.action = "loadNodeConfig";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onLoadNodeConfig",
+    "data": {
+        "nodeName": "04BF52213343C147E631B877BCEB17B794230EE551E85F58FA429C4BA03D690778CC384C6916C63DF36CB9E35C7E274FDB4E18491DFE3D611D347856D441CACC5AF9090B515F02AFC2DFBF56461EC83B5A4CD342466360D6CF82E6E40B637430AC4A329CCBC798DAF7D526AF9E3B3600E0BEA1BFAB8C160EF90128FAF67B19E45F37664F1E4B",
+        "licence": "04AADCC7103CD02626D228AFFBEF53F8242ECA4DDD6F179D30B622440666715CFBB6FD1D3678A2B25812DEA9917073E79A65F7ADE517F784DC76288EFCEB37ECAA1025E6903540702F729DA1C2ECCD93F4E6FAFCE40DF443E7FD74387169D0C6D927C7BB12882D0471C8D3E6F31B0316A42FC38F6DD9978D4351B23B2AD63E2244909E98F51185D32CB99B4AE4E22D3AB4C04027BB",
+        "expireTime": "Wed Aug 26 09:43:08 CST 2020",
+        "nodes": "[\"node1\",\"node2\",\"node3\"]",
+        "yjsPath": "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar",
+        "nodeCenter": "ws://127.0.0.1:1719/SCIDE/NodeCenter"
+    }
+}
+
+{
+    "status":true,
+    "action":"onLoadNodeConfig",
+    "data":{
+        "nodeName":"Node_180",
+        "peerID":"",
+        "masterAddress":"39.104.201.40:21031",
+        "licence":"04AADCC7103C",
+        "doipConfig":"{\\"LHSProxyAddress\\":\\"http://39.104.201.40:21042/\\",\\"ownerHandle\\":\\"86.5000.470/dou.TEST\\",\\"certPath\\":\\"keys/dou.TEST.keystore\\",\\"certPassword\\":\\"123456\\",\\"repoID\\":\\"86.5000.470/doip.vcg9Mu1gSq_bdw\\",\\"listeners\\":\\"[{\\\\\\"url\\\\\\":\\\\\\"tcp://39.104.201.40:21032\\\\\\",\\\\\\"protocolVersion\\\\\\":\\\\\\"2.1\\\\\\",\\\\\\"messageFormat\\\\\\":\\\\\\"packet\\\\\\"}]\\",\\"serviceDescription\\":\\"test local Contract Repository\\",\\"serviceName\\":\\"ContractEngine021\\"}",
+        "clusterConnected":"false",
+        "nodePubKey":"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5",
+        "ipPort":"",
+        "bdledger":"39.108.56.240:18091,39.108.56.12:1809139.104.70.160:18091 47.98.247.70:18091 47.98.248.208:18091 39.104.77.165:18091 47.98.249.131:18091",
+        "yjsPath":"/data/bdwaas/bdcontract/yjs.jar",
+        "nodeCenter":"ws://39.104.201.21040/SCIDE/NodeCenter"
+    }
+}
+
+
+
+
+
+

修改节点配置

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

updateConfig

key

要改的配置项

val

要更改的目标值

+

其中,key的可选项包括:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

key的示

val示例

说明

yjsPath

/User/xxx/cp/yjs.jar

合约进程启动所需的jar

dataChain

192.168.1.8:18090,182.173.2.3:18091

账本节点的ip与端口

nodeCenter

ws://127.0.0.1:18002

CenterPortal所在的ip/端口

nodeName

Node_180

字符串类型

masterAddress

192.168.3.2:18001

该NodePortal节点的ip和的TCP端口

+

其中NodePortal的TCP端口为Node的http/ws端口号+1。

+
+
+
+

修改节点名称

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

changeNodeName

data

新的节点名称

+
+
+
请求示例
+
var param = {};
+param.action = "changeNodeName";
+param.data = "NewNodeName";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onChangeNodeName",
+    "data": true
+}
+
+
+
+
+
+

修改节点YJS路径

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

changeYJSPath

data

节点服务器yjs.jar路径

+
+
+
请求示例
+
var param = {};
+param.action = "changeYJSPath";
+param.data = "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onChangeYJSPath",
+    "data": true
+}
+
+
+
+
+
+

修改NodeCenter

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

changeNodeCenter

data

节点服务器要连接的NodeCenterWebSocket路径

+
+
+
请求示例
+
var param = {};
+param.action = "changeNodeCenter";
+param.data = "ws://127.0.0.1:1719/SCIDE/NodeCenter";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onChangeNodeCenter",
+    "data": true
+}
+
+
+
+
+
+

修改账本节点

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

changeBDledger

data

数链节点的IP:port,用“,”隔开

+
+
+
请求示例
+
var param = {};
+param.action = "changeBDledger";
+param.data = "39.108.56.240:18091,39.108.56.12:18091";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onChangeBDledger",
+    "data": true
+}
+
+
+
+
+
+

上传节点Licence

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

uploadLicence

data

节点服务器的Licence内容

+
+
+
请求示例
+
var param = {};
+param.action = "uploadLicence";
+param.data = "04AADCC7103C";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onUploadLicence",
+    "data": true
+}
+
+
+
+
+
+

获取节点ID

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

getNodeID

+
+
+
请求示例
+
var param = {};
+param.action = "getNodeID";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status": true,
+    "action": "onGetNodeID",
+    "data": "0431…d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d"
+}
+
+
+
+
+
+

获取节点所在的可信执行集群

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

getNodeTrustUnits

data

节点ID

msgHandler

收到回复的回调函数, 可使用“建立连接”的msgHandler

ws

节点所属的NodeCenter的WebSocket地址

+
+
+
请求示例
+
centerportalws = createWssocket("ws://127.0.0.1:1718/NodeCenterWS",function() {
+var param = {};
+param.action = "getNodeTrustUnits";
+param.data = "0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d";
+centerportalws.send(JSON.stringify(param));
+}, msgHandler);
+
+
+
+
+
返回结果
+
{
+    "data": [{
+        "key": "0475c7b061...65e55_4063665700873624164",
+        "value": "[\"04541429c11b094…40009b4f06d\"]"
+    }],
+    "action": "onGetNodeTrustUnits"
+}
+
+
+
+
+
+
+

模板生成类

+
+

获取合约模板列表

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

getTemplateList

+
+
+
请求示例
+
req={};
+req.action = "getTemplateList";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "formDesc": {
+                "dbPWD": {
+                    "label": "密码",
+                    "type": "input"
+                },
+                "contractName": {
+                    "label": "合约名称",
+                    "type": "input"
+                },
+                "accessPolicy": {
+                    "label": "访问控制策略",
+                    "type": "input",
+                    "option": [
+                        {
+                            "text": "无访问控制",
+                            "value": "NAC"
+                        },
+                        {
+                            "text": "直接访问控制",
+                            "value": "DAC"
+                        },
+                        {
+                            "text": "基于角色的访问控制",
+                            "value": "RBAC"
+                        }
+                    ]
+                },
+                "dbUserName": {
+                    "label": "用户名",
+                    "type": "input"
+                },
+                "fieldList": {
+                    "label": "字段名",
+                    "type": "tag"
+                },
+                "dbUrl": {
+                    "label": "数据库链接",
+                    "type": "input"
+                },
+                "tableName": {
+                    "label": "表名",
+                    "type": "input"
+                }
+            },
+            "apiName": "generateMySQLProject"
+        },
+        {
+            "formDesc": {
+                "contractName": {
+                    "label": "合约名称",
+                    "type": "input"
+                },
+                "accessPolicy": {
+                    "label": "访问控制策略",
+                    "type": "input",
+                    "option": [
+                        {
+                            "text": "无访问控制",
+                            "value": "NAC"
+                        },
+                        {
+                            "text": "直接访问控制",
+                            "value": "DAC"
+                        },
+                        {
+                            "text": "基于角色的访问控制",
+                            "value": "RBAC"
+                        }
+                    ]
+                }
+            },
+            "apiName": "generateEmptyProject"
+        }
+    ],
+    "action": "onTemplateList"
+}
+
+
+
+
+
+

空白合约模板

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + +

字段

action

generateEmptyProject

contractName

字符串类型,合约名称

isPrivate

布尔类型,是否为私有项目

accessPolicy

若为“DAC”,则实现直接访问控制

+
+
+
请求示例
+
var req = {};
+req.contractName = "Empty22";
+req.action = "generateEmptyProject";
+req.accessPolicy = "DAC";
+//wssocket为建立好的连接
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\"]",
+    "executeTime":0,
+    "isPrivate":false
+}
+
+
+
+
+
+

MySQL接入合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

generateMySQLProject

contractName

字符串类型,合约名称

isPrivate

布尔类型,是否为私有项目

dbUrl

字符串类型,数据库的URI

dbUserName

字符串类型,数据库的用户名

dbPWD

字符串类型,数据库密码

accessPolicy

若为“DAC”,则实现直接访问控制,若为“NAC”则没有访问控制

tableName

字符串类型,数据库的表名

fieldList

字符串列表,数据库的字段列表

defaultAccept

布尔值,表示申请时是否默认有权

+
+
+
请求示例
+
var req = {};
+req.contractName = "MySQLFromTemplate";
+req.action = "generateMySQLProject";
+req.pubKey = global.sm2Key.publicKey;
+req.isPrivate = true;
+req.tableName = "data";
+req.dbUrl = "jdbc:mysql://xxx:xxx/xxx";
+req.dbUserName = "loushuai";
+req.dbPWD = "loushuai";
+req.fieldList = [{"name":"名字","code":"*"}];
+req.basicInfo={"type":"所属分类","name":"资源名称"};
+req.accessPolicy = "DAC";
+req.defaultAccept = true;
+//global.wssocket为建立好的连接
+global.wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+

CSV接入合约

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +

字段

action

generateCSVProject

contractName

字符串类型,合约名称

base64EncodedData

字符串类型,通过base64编码后的CSV文件内容

isPrivate

可选字段,布尔类型,是否为私有项目

accessPolicy

若为“DAC”,则实现直接访问控制,若为“NAC”则没有访问控制

defaultAccept

可选字段,布尔值,表示申请时是否默认有权

+
+
+
请求示例
+
var req = {};
+req.contractName = "CSVFromTemplate";
+req.action = "generateCSVProject";
+req.pubKey = global.sm2Key.publicKey;
+req.isPrivate = true;
+req.tableName = "data";
+req.accessPolicy = "DAC";
+req.defaultAccept = true;
+req.base64EncodedData = "bmFtZSwgc2NvcmUsCmphY2ssIDkwLApsdWN5LCA5MQo=";
+//global.wssocket为建立好的连接
+global.wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+
+
+
+

路由节点WebSocket接口

+
+

用户管理类

+
+

获取Session

+

登录前获取session以便进行签名。

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

getSessionID

+
+
+
请求示例
+
var req = {};
+req.action = "getSessionID";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action": "onSessionID",
+    "session": "9782323_session"
+}
+
+
+
+
+
+

用户登录

+

用户进行公私钥身份验证,需先调用“getSessionID”获取sessionID以便于签名。

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

login

+
+
+
请求示例
+
var loginParam = {};
+loginParam.pubKey = global.sm2Key.publicKey;
+loginParam.signature = sm2.doSignature(global.session,
+            global.sm2Key.privateKey);
+loginParam.action = "login";
+wssocket.send(JSON.stringify(loginParam));
+
+
+
+
+
返回结果示例
+
{
+    "action": "onLogin",
+    "data": "CenterManager"
+}
+
+
+
+
+
+

用户获取当前角色(删除)

+

用户根据登录时的公钥获取对应的角色,如果是第一次登录则此时的公钥默认称为准入管理员

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

getRole

+
+
+
请求示例
+
var param = {};
+param.action = "getRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+    "action": "onGetRole",
+    "data": "CenterManager"
+}
+
+
+
+
+
+

申请角色

+

在准入管理员界面可以申请称为组网中某个节点的节点管理员

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

applyRole

role

申请的角色名称

+
+
+
请求示例
+
var param = {};
+param.action = "applyRole";
+param.role="
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+    "action": "onApplyRole",
+    "data": "failed"
+}
+
+
+
+
+
+

添加节点

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

addNode

nodePubKey

要添加的节点公钥

+
+
+
+

请求示例

+
var req = {};
+//某节点的publicKey可通过连接该节点,并通过"获取节点配置信息"接口获取
+req.nodePubKey = publicKey;
+req.action = "addNode";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+

删除用户角色

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

delete

pubKey

对应用户的公钥

+
+
+
请求示例
+
var deleteInfo = {};
+deleteInfo.pubKey = user.publicKey;
+deleteInfo.action = "delete";
+wssocket.send(JSON.stringify(deleteInfo));
+
+
+
+
+
返回结果示例
+
{
+    "action": "onDelete",
+    "data": "success"
+}
+
+
+
+
+
+

查看授权用户列表

+

查看准入管理员当前组网中已经授权的节点管理员

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listAllUsers

+
+
+
请求示例
+
var param = {};
+param.action = "onListAllUsers";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+    "action": "onListAllUsers",
+     "kv": {
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": " NodeManager"
+    },
+    "time": {
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": 1587398989914
+    }
+}
+
+
+
+
+
+

查看申请用户列表

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listApplyList

+
+
+
请求示例
+
var param = {};
+param.action = "onListApplyList";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onListApplyList",
+     "kv": {
+        "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7",
+        "value": " NodeManager"
+    },
+    "time": {
+        "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7",
+        "value": 1587398989914
+    }
+}
+
+
+
+
+
+

查看用户类型分布

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

queryUserStat

+
+
+
请求示例
+
var param = {};
+param.action = "onQueryUserStat";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+    "action": "onQueryUserStat",
+    "userListCount": 3,
+    "applyListCount":0
+}
+
+
+
+
+
+
+

节点管理类

+
+

查看节点列表

+

查看该用户有权限查看的节点列表(仅准入管理员及合约管理者可用)

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listNodes

+
+
+
请求示例
+
var param = {};
+param.action = "listNodes";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "offline": [{
+        "key": "0431e31...40009b4f06d",
+        "value": "0431e311bd708...b4f06d"
+    }],
+    "action": "onListNodes",
+    "online": [{
+        "contracts": [],
+        "pubKey": "0431e311...09b4f06d",
+        "nodeName": "NewNodeName",
+        "udpID": "528822126",
+        "cimanager": ""
+    }]
+}
+
+
+
+
+
+

查看可信执行集群列表

+

查看该用户有权限查看的节点列表(仅中心管理员及合约管理者可用)

+
+
参数
+ ++++ + + + + + + + + + + +

字段

action

listTrustUnits

+
+
+
请求示例
+
var param = {};
+param.action = "listTrustUnits";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "data": [{
+        "key": "0470b2f27f4f6…1cb855f1ecec11",
+        "value": "[...]"
+    }],
+    "action": "onListTrustUnits"
+}
+
+
+
+
+
+

建立可信执行集群

+
+
参数
+ ++++ + + + + + + + + + + + + + + + + +

字段

action

createTrustUnit

data

节点公钥组成的Json数组

Msg

集群名称

+
+
+
请求示例
+
var param = {};
+param.action = "createTrustUnit";
+param.data = "[\"382r0934309t...\",\"345343rr3f34...\"]";
+param.msg = "newUnit1";
+global.wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onCreateTrustUnit",
+    "status": "Success"
+}
+
+
+
+
+
+

删除可信执行集群

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

deleteTrustUnit

data

可信执行集群ID

+
+
+
请求示例
+
var param = {};
+param.action = "deleteTrustUnit";
+param.data = "0475d34rf3434..._1583410158761";
+global.wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "action": "onDeleteTrustUnit",
+    "status": "Success"
+}
+
+
+
+
+
+
+

日志查看类

+
+

查看组网管理操作的统计

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

queryActionLog

date

当前时间

+
+
+
请求示例
+
request.action = "onQueryActionLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{   "action":"onQueryActionLog",
+     "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]"
+}
+
+
+
+
+
+

查看本地近n日合约日志

+
+
参数
+ ++++ + + + + + + + + + + + + + +

字段

action

listLocalContractLog

date

当前时间

+
+
+
请求示例
+
request.action = "listLocalContractLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7b...\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]"
+}
+
+
+
+
+
+
+
+
+

Bash接口

+

已废弃。可使用BDWareConfigTool代替。 通过命令行发送Socket指令, +执行调用ContractController类中方法, 完成以下功能. +(需要在本机的``1615``端口运行ContractManager实例)

+
+Bash接口功能示意图 +

Bash接口功能示意图

+
+
+

指令

+
java -jar yjs.jar function_name arguments
+
+
+

function_name为调用的方法名;

+

arguments为方法参数.

+
+
+

启动合约

+
+

参数

+

function_namestartContract;

+

arguments为启动合约需要的参数, 包括合约类型type, +合约IDid, 合约脚本script.

+
+
+

指令示例

+
java -jar yjs.jar startContract "{\"type\":\"Algorigthm\",\"id\":\"656565\",\"script\":\"contract c{function main(arg){return arg/1.0+1;}}\"}"
+
+
+
+
+
+

调用合约

+
+

参数

+

function_nameexecuteContract;

+

arguments为调用合约需要的参数, 包括调用参数arg, +合约IDcontractID.

+
+
+

指令示例

+
java -jar yjs.jar executeContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}"
+
+
+
+
+
+

停止合约

+
+

参数

+

function_namestopContract;

+

arguments为调用合约需要的参数, 即合约IDcontractID.

+
+
+

指令示例

+
java -jar yjs.jar stopContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}"
+
+
+
+
+
+

停止全部合约

+
+

参数

+

function_namestopAllContracts.

+
+
+

指令示例

+
java -jar yjs.jar stopAllContracts
+
+
+
+
+
+

查询全部合约

+
+

参数

+

function_namelistContracts.

+
+
+

指令示例

+
java -jar yjs.jar listContracts
+
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/IDEUsage.html b/doc/IDEUsage.html new file mode 100644 index 0000000..faf149f --- /dev/null +++ b/doc/IDEUsage.html @@ -0,0 +1,833 @@ + + + + + + + + + + BDContract管理界面 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract管理界面

+
+
+

合约节点管理界面

+

该界面的使用地址为:NodePortal.html

+
+

用户管理菜单

+

用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。

+
+

概览

+

nodeUserManager +节点用户管理页面一共有四个模块:用户情况、用户活跃统计、授权用户管理、未授权用户管理。

+
+
+

用户类型分布

+

主要统计当前节点管理员所拥有的四种角色的数量:合约提供者、合约管理员、合约使用者 +userList

+
+
+

用户活跃统计

+

userActive 统计30天之内登录授权申请的次数

+
+
+

当前用户信息

+

nodeInfo * +在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录节点管理员界面,可以将自己的公私钥复制到这个文本框中。 +* +将自己的公私钥复制完成之后要点击导入公钥,将公钥加入到节点管理员本地 +* +然后在本地公钥中可以看见公钥的前五位,选择自己的公钥,将在我的权限中展示出当前选择的公钥的角色,如果是还没有在中心管理员认证的节点则默认为Anonymous +* +如果不是节点管理员,想要加入某个中心管理员的网络,那么要在中心管理员所在的用户管理中用自己的公私钥导入后进行认证。 +* +如果想要行使更多关于合约的操作,则需要认证不同的角色:合约管理员、合约使用者、合约提供者,然后进行角色认证

+
+
+

授权与非授权用户列表

+

roleAuth +在节点管理员认证角色之后,节点管理员登录会在未授权角色管理表格中看见带有公钥的申请信息,如果同意,则点击授权,如果不同意点击忽略就可以。 +授权之后将在授权角色管理表格中看见授权后的节点列表。如果节点管理员想要移除某个节点的角色,则在授权角色管理列表中删除即可。

+
+
+
+

合约代码管理菜单

+
+codeManageMenu +

codeManageMenu

+
+
+

合约文件

+
+codeManage1 +

codeManage1

+
+

在合约代码管理菜单中,用户可以看到公共合约以及个人私有合约。 +codeManage1-1

+

对于公共合约,节点管理员可以对其中文件进行删除和上传操作,可以对合约项目进行下载和删除操作。 +codeManage1-2

+

对于私有合约,合约提供者可以对其中文件进行删除和上传操作,可以对合约项目进行下载、删除和传至公共合约目录操作。

+

以下是对合约文件进行操作的示例。

+
+
+

上传文件

+
+codeManage6 +

codeManage6

+
+
+
+

删除

+
+codeManage5 +

codeManage5

+
+
+
+

传至公共

+
+codeManage7 +

codeManage7

+
+
+
+

下拉框

+
+codeManage2 +

codeManage2

+
+

四个下拉框中,可以分别对合约状态保存模式、已启动合约实例、节点所在集群以及结果校验方式进行选择。

+
+
+

按钮操作

+
+codeManage3 +

codeManage3

+
+
+
+

启动

+

在文件列表中选择合约文件之后,在合约运行模式中选择“单节点执行”,点击启动按钮,会启动指定文件,并在结果显示框中显示返回结果。

+
+
+

启动P2P集群合约

+

在文件列表中选择合约文件之后,在合约运行模式中选择该可信合约运行的合约集群,点击启动按钮,会在该集群的所有节点上启动指定文件,并在结果显示框中显示返回结果。

+
+
+

启动全部

+

在合约运行模式中选择“单节点执行”,点击启动全部按钮,会启动合约文件列表中所有合约。

+
+
+

停止P2P集群合约

+

在已启动合约实例的下拉框中选择一个合约实例,在合约运行模式中选择该可信合约运行的合约集群,点击停止按钮,会在该集群的所有节点上终止这个合约进程。

+
+
+

停止

+

在已启动合约实例的下拉框中选择一个合约实例,点击停止按钮,会终止这个合约进程。

+
+
+

停止全部

+

点击停止全部按钮,会停止该节点上运行的所有合约实例。

+
+
+

静态分析

+

在合约文件列表中选择合约文件,并在合约实例下拉框中选择合约实例,点击静态分析按钮,会对该合约进行静态分析,并在结果显示框中显示返回结果。

+
+
+

分发合约

+

在合约文件列表中选择合约项目,并在合约运行模式中选择一个集群,点击分发合约按钮,会将该合约项目打包为ypk分发给这个集群中的所有节点。

+
+
+

返回结果

+
+codeManage4 +

codeManage4

+
+

返回结果显示中显示一些操作的返回结果。

+
+
+

合约权限配置

+

在启动合约之后,如果当前用户的角色可以查看已经启动合约进程,那么在选定查看合约进程时将会在右下方展示当前合约的IO权限。 +permissionShow

+

如果选中的合约没有IO权限,则在当前权限的展示框中提示当前合约没有IO权限 +nullPermission

+

当前用户是合约管理员时可以对已有的合约IO权限进行修改。系统会提示修改后合约将有可能不会正常运行,如果还是确定要取消,那么点击确定 +即可,反之点击关闭 updatePermission

+

点击关闭或者打开之后,下一次查看同一个合约代码的进程将会默认显示最近一次修改之后的IO权限。 +closePermission

+
+
+
+

合约实例管理菜单

+
+nodeInstancesPage +

nodeInstancesPage

+
+

合约实例管理菜单显示了该节点当前的所有合约实例, +用户可查看合约实例的状态, 并对合约实例进行执行或状态迁移的操作.

+
+

合约实例列表

+
+nodeInstancesList +

nodeInstancesList

+
+

该列表显示了当前节点的所有合约实例信息, 包括合约ID, 合约名称, +合约类型合约状态, 合约进程端口, 合约调用次数, 合约流量, 及合约占用内存, +集群合约的结果校验模式.

+
+
+

合约实例执行

+
+chooseInstance +

chooseInstance

+
+

用户可在合约实例的选择下拉框中选择合约实例, 对该合约实例进行操作.

+
+intanceExecute +

intanceExecute

+
+

选择合约实例后, 用户可在“方法”的下拉框中选择该合约的方法名, +在“参数”输入框中输入方法的参数, 点击“执行”.

+

用户还可点击“动态分析执行”进行带有动态分析结果的执行.

+

若该合约为单点合约, 则合约在单点执行; 若该合约为集群合约, +则该合约在该集群的所有节点上执行.

+
+
+

合约实例执行结果

+
+executeResult +

executeResult

+
+

合约实例的执行完成后的结果显示在“执行结果”区域中, 包括该次执行的ID, +执行成功/失败, 执行时间, 及执行结果.

+
+analysisExecuteResult +

analysisExecuteResult

+
+

若该合约的执行方式为“动态分析执行”, 则结果框内除执行结果, +还会显示该次执行的动态分析结果.

+
+
+

合约状态迁移

+
+memoryDump +

memoryDump

+
+

对于支持用户手动迁移的合约实例, +用户可点击“本地状态保存”对合约实例的状态进行保存, +或从合约的TimeTravel列表中选择已保存的合约实例, +将合约状态迁移到对应时刻.

+
+
+
+

日志管理菜单

+
+logMenu +

logMenu

+
+

该菜单是对该节点本地节点日志以及合约日志的统计结果展示。

+

其中,节点管理员可以查看节点日志的相关数据;合约管理者及合约使用者可以查看该节点本地合约日志的相关数据。

+
+

日志统计图

+
+log1 +

log1

+
+
+
+

各类平台操作百分比

+

该图默认显示近2日各类平台操作占比的饼图,其中平台操作分为登陆类、用户类、日志类、合约类、维护类以及其他类这六类。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比会同步更新。

+
+
+

各类合约操作百分比

+

合约操作分为启动、终止、静态分析和执行这四类,该图为近2日对各类合约操作占比的饼图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比会同步更新。

+
+
+

每日平台使用统计

+

该图为近2日平台操作次数统计的折线图。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日平台使用统计折线图会同步更新。

+
+
+

每日合约使用统计

+

该图为近2日对该节点上合约的操作次数统计的折线图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日合约使用统计折线图会同步更新。

+
+
+

日志详情

+
+
+

节点日志详情

+
+log2 +

log2

+
+

节点日志详情表是对节点日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比和每日平台使用统计会同步更新。

+
+
+

合约日志详情

+
+log3 +

log3

+
+

合约日志详情表是对合约日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比和每日合约使用统计会同步更新。

+
+
+
+

节点管理菜单

+
+nodeConfig +

nodeConfig

+
+

节点管理菜单显示了该节点的配置信息及所属可信执行集群信息.

+
+

节点配置

+
+nodeConfigChange +

nodeConfigChange

+
+

节点管理员可查看该节点的配置信息, 包括节点名称, 节点YJS路径, +节点的网络中心节点, 节点管理员还可对以上配置进行修改.

+

若节点管理员修改了节点的网络中心, 该节点后重新想改节点连接, +整个页面刷新重载.

+
+
+

节点可信执行集群列表

+
+nodeUnits +

nodeUnits

+
+

节点管理员可查看节点所属的可信执行集群信息, 包括集群创建者, 集群ID, +集群中节点数目, 集群中节点的信息.

+
+
+
+

节点Licence配置

+
+nodeLicence +

nodeLicence

+
+

用户可以查看该节点的Licence及过期时间, 还可申请Licence, 上传Licence, +保存节点UUID.

+
+
+
+
+

智能合约在线编辑器

+
+

用户与账号

+
+

创建账号

+
+
+

申请授权

+
+
+
+

创建项目

+
+

新建文件

+
+
+

上传文件

+
+
+
+

启动合约

+
+contractMode +

contractMode

+
+

####正常模式 点击左侧启动按钮,以正常模式启动合约。

+

####debug模式 +点击右侧debug按钮,以debug模式启动合约。目前约定debug模式合约通过executeContract调用正常模式合约时,返回正常模式合约文档中的返回结果示例。

+
+
+

调用合约

+

###生成文档 genReadme

+

启动合约后点击“生成文档”按钮,可以通过各export函数的@Description / +@Param / @Result 对合约进行调用及结果返回,从而生成合约的说明文档。

+
+
+
+
+

路由准入管理界面

+
+

权限申请与授权

+
+
+

仪表盘

+

仪表盘为提供对准入节点中用户数量,合约数量,节点数量的概览。

+
+
+

整体视图

+

dashboard +一共分为四个模块,一个模块是用户、合约、节点数量的概览,然后分别是这三个数量的详细分类的数据统计情况。

+
+
+

节点数目

+

node 当前在线和离线节点统计

+
+
+

用户类型分布

+

userAll +当前准入节点所在组网中的节点管理员、准入管理员的数量和申请中节点的数量

+
+
+

合约调用情况

+

contract +当前准入节点所在组网中所有合约中事件、多点执行、ws调用、Http调用的折线统计图。

+
+
+

用户管理

+

用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。

+
+
+

概览

+

centerManager 用户管理页面一共有四个模块。

+
+
+

用户类型分布

+

主要统计当前中心管理员所管理的网络中有多少节点管理员,多少个中心管理以及申请节点管理员的数量 +userList

+
+
+

30天内的申请情况统计

+

userApplyGraph +统计30天之内申请节点管理员的数量和授权成为节点管理员的数量

+
+
+

当前用户信息

+

authNodeManager * +在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录中心管理员界面,可以将自己的公私钥复制到这个文本框中。 +* +将自己的公私钥复制完成之后要点击导入公钥,将公钥加入到中心管理员本地 +* +然后在本地公钥中可以看见公钥的前五位,选择自己的公钥,将在我的权限中展示出当前选择的公钥的角色,如果是中心管理员则拥有中心管理员的一切权限。 +* +如果不是中心管理员或者节点管理员,想要加入当前中心管理员的网络,那么可以在下面的选择框中选中节点管理员,进行角色认证

+
+
+

授权与非授权用户列表

+

在中心管理员当前用户信息申请之后,中心管理员登录会在未授权用户管理表格中看见带有公钥的申请信息,如果同意,则点击授权,如果不同意点击忽略就可以,此时这个申请就无效。 +authMan +授权之后将在授权用户管理表格中看见授权后的节点列表。如果中心管理员想要移除某个节点管理员的某项角色,则在授权用户管理列表中选择相应的角色,然后点击删除即可删除选中的角色。 +authMana

+
+
+

节点管理

+
+centerNodePage +

centerNodePage

+
+

节点管理为Manager对连接到自己的Cluster节点进行管理的页面, +仅Manager管理员及合约管理者可见. +Manager管理员及合约管理者可在本页面查看节点信息, 并管理可信执行集群.

+
+
+

概览

+
+centerNodePreview +

centerNodePreview

+
+

概览中显示了该Manager节点所管理的所有节点的统计信息, 包括总节点数量, +总合约数量, 总订阅事件数量, 及可信执行集群数量, +右侧的饼图则为节点的分别处于Online/Offline的数量统计.

+
+
+

节点列表

+
+centerNodeList +

centerNodeList

+
+

节点列表显示了用户有权限查看的节点信息(Manager管理员可查看全部节点, +合约管理者可查看自己负责管理的Online节点). 包括节点的名称, 状态, +合约数目, 订阅事件数目, 用于节点间P2P通信的PeerID, +用于节点间UDP通信的UDPID, 及节点公钥.

+
+
+

可信执行集群列表

+
+centerNodeUnits +

centerNodeUnits

+
+

可信执行集群列表显示了用户有权限查看的可信执行集群信息(Manager管理员可查看全部集群, +合约管理者可查看自己创建的集群). 包括集群的创建者, 集群ID, +集群中节点数目, 以及集群中节点的信息.

+

用户可点击列表表项的“删除”按钮, 将该集群删除.

+
+
+

创建可信执行集群

+
+centerNodeUnitCreate +

centerNodeUnitCreate

+
+

用户可以通过多选节点, 创建新的可信执行集群. +用户可以选择的节点为自己有权限查看的节点, +即Manager管理员从全部节点中选择, +合约管理者可从自己负责管理的Online节点中选择). 选择后点击提交, +即可看到创建成功的提示信息, 该集群将随即显示在可信执行集群列表中. +集群名称由创建者选取, 不能含有双引号, +该名称为合约管理者选择集群时的可见标识.

+
+
+

日志管理

+

日志管理主要展示准入节点的各项日志信息,一共分为六个模块。 ### 概览 +log

+
+
+

管理操作分类统计(2日)

+

operator +两日内所有管理类操作的统计饼图,管理类操作主要分为登录类、日志类、维护类、用户类。

+
+
+

管理操作每日统计(2日)

+

everyLog 两日内管理类所有的操作每日操作统计

+
+
+

合约操作分类统计(2日)

+

contractLog +两日内合约操作分类统计饼图,合约操作主要分为连接类和状态更新类。

+
+
+

合约操作每日统计(2日)

+

contracteveryLog 两日内合约操作数量折线统计图。

+
+
+

管理操作日志列表

+

opList +管理操作日志的详细信息列表。包括日志时间,管理操作名称,操作对应的节点公钥。默认展示范围是两天,可以自定义获取日志的天数。

+
+
+

合约操作日志列表

+

contractList +合约操作日志详细信息列表。包括日志产生时间,合约操作名称,合约操作节点公钥。默认展示范围是两天,可以自定义获取日志的天数。

+
+
+

设置

+

设置页面是节点证书的状态展示以及配置节点证书

+
+
+

概览

+
+set +

set

+
+
+
+

证书状态

+

licence 证书状态主要包括许可到期时间和许可节点数量。

+
+
+

配置证书

+

plicence 配置证书模块可以下载节点ID文件或者输入证书信息进行提交。

+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/InstallTips.html b/doc/InstallTips.html new file mode 100644 index 0000000..2a20553 --- /dev/null +++ b/doc/InstallTips.html @@ -0,0 +1,406 @@ + + + + + + + + + + BDContract安装说明 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract安装说明

+
+
+

依赖环境的安装

+

1.安装Java1.8环境。

+

例如,在Ubuntu下使用apt-get进行安装:

+
apt-get install openjdk-8-jre
+
+
+

在Centos环境下,使用yum进行安装:

+
yum install java-1.8.0-openjdk
+
+
+

如果是离线环境,可先下载openjdk的安装包后进行离线安装。

+

Ubuntu下

+
dpkg -i jdk-8uxxxxx.deb
+
+
+

在Centos环境下,使用yum进行离线安装:

+
yum localinstall jdk-8u271-linux-xxx.rpm
+
+
+

2.安装wget与unzip。 例如,在Ubuntu下使用apt-get进行安装:

+
apt-get install unzip
+apt-get install wget
+
+
+
+
+
+

网络拓扑说明

+

部署数瑞智能合约引擎最小仅需一个节点,此时可用作调试、测试,不能通过多节点模式来实现可信的计算。 +单节点部署时,可通过配置账本实现“防抵赖”的计算,但不能实现“难篡改”的计算。

+

多节点部署时可参考下图,包含三种逻辑节点,同一虚拟机可安装一至三种节点。

+

1)账本节点。即数瑞图式账本。

+

2)合约节点。运行代码逻辑,并通过内存缓存实现高响应的模块。与其他合约节点组成可信计算网络。

+

3)路由节点。各个合约节点的路由信息。一般单个路由节点可支持最高1000合约节点。可视情况部署多个路由节点,并在路由节点之间配置实现更大规模的节点组网。

+

一般地,同一虚拟机下,会部署合约节点与账本节点

+
+deploytopology +

deploytopology

+
+
+
+
+

智能合约节点安装

+

打开安装包下载链接 +其中,下载bdserver-lite.zipbdserver.zip,其中,bdserver.zip包含更多示例和文档。 +下载之后解压并启动。

+
unzip -d ./bdserver bdserver-lite.zip
+cd bdserver
+chmod +x *.sh
+sh cmstart.sh
+
+
+
+
+
+

路由准入节点安装

+

打开安装包下载链接 +其中,下载bdserver-cluster.zip。 下载之后解压并启动。

+
unzip -d ./bdcluster bdserver-cluster.zip
+cd bdcluster
+chmod +x *.sh
+sh ncstart.sh
+
+
+
+
+
+

文件说明

+
+

智能合约节点

+
+bdserver目录 +

bdserver目录

+
+

该目录下的文件说明:

+

1.cmstart.sh +该脚本用于启动合约引擎。合约引擎默认监听8080端口,可通过修改cmstart.sh来修改合约引擎的监听端口。

+

2.BDWareProjectDir 该目录存放了本节点的所有合约项目。

+

3.WebContent 该目录存放了本节点的前端代码。

+

4.cp, 该目录存放了yjs.jar,为启动合约实例所需的jar。

+

5.bdserver.jar 对外提供http/websocket的服务器逻辑。

+

6.updateContract.sh 用于升级的脚本。

+
+
+

路由准入节点

+

安装脚本会自动下载安装并解压为bdcluster目录。 该目录下的文件说明:

+

1.ncstart.sh +该脚本用于启动节点准入中心。默认监听1718端口。可通过修改ncstart.sh来修改监听的端口。

+

2.WebContent 该目录存放了准入中心的前端代码。

+

3.bdcluster.jar 准入中心的后端。

+
+
+
+
+

升级流程

+
+

合约节点

+

在命令行中输入:

+
sh updateContract.sh
+
+
+

亦可通过public.internetapi.cn,下载最新文件,单独升级yjs.zip/bdserver-jar.zip/AgentWebContent来升级。

+
+
+

路由准入节点

+
sh updateCluster.sh
+
+
+

亦可通过public.internetapi.cn,下载最新文件,单独升级bdserver-cluster.zip/ClusterWebContent.zip来升级。

+
+
+
+
+

使用说明

+
+

通过参考界面使用

+

当保留了WebContent目录的情况下,可使用浏览器进行配置。 +更多请使用见左侧文档BDContract参考界面使用说明

+
+

BDWare OnlineIDE

+

打开BDWare OnlineIDE

+
+
+

BDWare NodePortal

+

打开BDWare NodePortal

+

如需组网,使用跨节点功能,则需安装路由准入中心。并按以下步骤进行配置。涉及两组公私钥。 +第一组公私钥为合约节点的、有NodeManager权限的公私钥。 +第二组公私钥为路由准入节点的、有CenterManager权限的公私钥。

+

1.打开NodePortal.html,复制该节点的NodeManager公私钥。

+

2.打开CenterPortal.html,点击右上角,将上述的NodeManager公私钥导入;并选择“NodeManager”进行身份认证。

+

3.在CenterPortal.html中切换CenterManager的公私钥,点左侧的“用户管理”,通过NodeManager的认证请求。

+

4.使用NodeManager权限的公私钥打开NodePortal.html,点击:“节点管理”菜单,并配置加入网络。 +其中,加入网络的格式为:ws://centerportal的ip:端口+1。 配置示例

+
+
+
+

通过SDK使用

+
+

基础知识

+

Websocket

+

Sm2加密的使用

+
+
+

SDK下载

+
    +
  1. Java版本的客户端下载:BDWareJavaClient。具体使用说明请下载后解压,查看README.md,并参考ContractAPI

  2. +
+

2.Javascript版本的客户端下载:BDWareWebClient。具体使用说明请下载后解压,查看README.md,并参考ContractAPI

+

3.配置工具BDWareConfigTool。具体说明请下载后解压,使用以下命令查看帮助:

+
java -jar java-client.jar -h
+
+
+
+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/Introduction.html b/doc/Introduction.html new file mode 100644 index 0000000..e736593 --- /dev/null +++ b/doc/Introduction.html @@ -0,0 +1,552 @@ + + + + + + + + + + BDContract介绍 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract介绍

+
+
+

什么是BDContract?

+

北大数瑞是面向大数据场景的数据资源、IoT资源、云资源的管理、调度平台。BDContract是一个可信计算框架,计算逻辑以智能合约的方式表达。通过”随机“和”冗余计算“的方式实现智能合约的可信执行。BDContract在保证智能合约的可用性、可靠性的同时,着重提升执行效率和安全性。

+
+
+
+

特点

+
    +
  1. 支持多种执行模式,权衡可用性、可靠性、正确性和效率。

  2. +
  3. 接入各种数据源。

  4. +
  5. 支持合约的细粒度监测。

  6. +
  7. 支持合约的状态。

  8. +
  9. 访问控制。

  10. +
  11. 支撑跨语言调用。

  12. +
+
+
+
+

更新日志

+
    +
  • v1.4.3 2021年6月9日

    +
      +
    • 修复SSL Renegotiate Bug

    • +
    • 实现内存不足时自动Hangup-Resume

    • +
    • 实现contract meta的硬盘持久化

    • +
    +
  • +
  • v1.4.1 2021年5月26日

    +
      +
    • 实现了事件机制中的事件语义,支持“至少一次”、“至多一次”和“只有一次”

    • +
    • 优化了合约模板

    • +
    • 增加模板配置文件

    • +
    • 优化了MockTemplate注解

    • +
    +
  • +
  • v1.4.0 2021年5月9日

    +
      +
    • 优化了ACTemplate

    • +
    • 完善了DoRepo的配置联动

    • +
    +
  • +
  • v1.3.9 2021年4月22日

    +
      +
    • 修复了doipConfig在updateConfig中不支持的bug

    • +
    • test-tool支持了sudo

    • +
    • 优化了contract-template中的ACTemplate模板

    • +
    +
  • +
  • v1.3.6 2021年4月21日

    +
      +
    • 修复了docker中无法获取cpuid的问题

    • +
    +
  • +
  • v1.3.6 2021年4月16日

    +
      +
    • 修复了部分bug

    • +
    • 修复了GRPCPool线程数量不足导致排队的bug

    • +
    • 修复了requestID分配在压力测试下可能重复的bug

    • +
    +
  • +
  • v1.3.5 2021年3月31日

    +
      +
    • 修复了部分bug

    • +
    • http的合约调用部分增加了简单拥塞控制策略

    • +
    • 稳定性提升

    • +
    +
  • +
  • v1.3.0 2021年2月1日

    +
      +
    • 优化心跳机制

    • +
    • 修复部分Bug

    • +
    • 更新SM2/SM3库

    • +
    • 更新前端签名计算方式

    • +
    +
  • +
  • v1.2.0 2020年12月11日

    +
      +
    • 优化了多节点执行模式

    • +
    • 优化了合约master路由的逻辑

    • +
    • 修复了部分bug

    • +
    • 修复文件系统相关的漏洞

    • +
    +
  • +
  • v1.1.0 2020年9月

    +
      +
    • 支持https,并更新了该部分文档

    • +
    +
  • +
  • v1.0.9 2020年8月27日

    +
      +
    • 完善IO相关工具类的文档

    • +
    • 优化合约模板:DAC持久化

    • +
    +
  • +
  • v1.0.7 2020年8月13日

    +
      +
    • 优化合约日志、账本接口

    • +
    • 优化相关接口的文档

    • +
    • 提供合约模板的websocket接口

    • +
    • 自动编译bug修复

    • +
    +
  • +
  • v1.0.5 2020年7月25日

    +
      +
    • 弱化NC的中心化作用,集群点对点连接。

    • +
    • 优化bdwareclient

    • +
    • TODO MemoryDurable

    • +
    +
  • +
  • v1.0.2 2020年7月22日

    +
      +
    • 修复CentOS7下Too Many Opened Files的Bug

    • +
    • 修复权限Bug

    • +
    • 增加权限说明

    • +
    • 修复MySQLUtil的bug

    • +
    • 升级BDLedger版本

    • +
    +
  • +
  • v1.0.1 2020年7月5日

    +
      +
    • 更新了NodePortal/CenterPortal的UI。

    • +
    • 修改了编译流程,在NodePortal中可查看编译结果,在OnlineIDE中可手动/启动时编译

    • +
    • 修改了合约分发逻辑,以编译后ypk作为分发的文件

    • +
    • 支持public目录下的ypk在多节点模式下执行时,合约故障自动恢复

    • +
    +
  • +
  • v0.99 2020年6月22日

    +
      +
    • 自定义合约方法的计费

    • +
    • 新增了GasExample、Incentives示例

    • +
    • 在客户端实现了“校验多点结果”,并优化了结果返回的方式

    • +
    • 修复断线重连后无权限提示

    • +
    +
  • +
  • v0.97 2020年5月25日

    +
      +
    • cpu等资源的计量:gas机制

    • +
    • onlineIDE.html 支持上传多个文件

    • +
    • udp方式组网进行多点执行[无定序消息]

    • +
    • bdwareclient.html,修复只包含计算逻辑的调用示例生成前缀错误

    • +
    +
  • +
  • v0.95 2020年5月19日

    +
      +
    • 修复了onlineIDE.html在的pathname有前缀时不能正确跳转bdwareclient的bug。

    • +
    • 修复了bdwareclient的pathname有前缀时自动提取url的bug。

    • +
    • 启用了合约的权限

    • +
    • 增加了NodePortal.html/OnlineIDE.html和bdwareclient.html中无权限时的提醒

    • +
    +
  • +
  • v0.90 2020年5月9日

    +
      +
    • 更改了yjs.jar/bdserver.jar的打包方式

    • +
    • 更新了install.sh/update.sh

    • +
    • onlineIDE的修改后提醒

    • +
    • onlineIDE标签页自适应宽度

    • +
    • 文件接口隔离

    • +
    +
  • +
  • v0.8 2020年4月26日

    +
      +
    • 完善文档界面和优化SDK提供方式

    • +
    • 数瑞Web客户端,客户端中所有的数据处理和如何对处理后的数据进行渲染均来自合约调用,实现可信Web应用。

    • +
    +
  • +
  • v0.78 2020年4月13日

    +
      +
    • 合约调用DAC示例

    • +
    • 支持动态修改IO权限

    • +
    • 支持合约状态自定义备份(定时)策略

    • +
    • 修复部分页面bug

    • +
    • 日志展示优化

    • +
    • 优化账本日志展示

    • +
    • 启用部分权限访问控制

    • +
    +
  • +
  • v0.7 2020年3月25日

    +
      +
    • 支持多种角色的访问控制

    • +
    • 更新了UI

    • +
    +
  • +
  • v0.6 2020年2月14日

    +
      +
    • 优化了合约进程间的通讯

    • +
    • 尝试接入P2P网络

    • +
    +
  • +
  • v0.5 2019年12月10日

    +
      +
    • 完善了3种智能合约状态记录-回放策略

    • +
    • 支持了最简单的多点执行算法(不同步)

    • +
    +
  • +
  • v0.45 2019年9月2日

    +
      +
    • 初步实现PBFT算法

    • +
    +
  • +
  • v0.4 2019年5月10日

    +
      +
    • 支持memory dump

    • +
    +
  • +
  • v0.35 2019年4月26日

    +
      +
    • 实现合约的静态分析框架

    • +
    • 支持事件的发布-订阅

    • +
    +
  • +
  • v0.3 2019年1月8日

    +
      +
    • 支持账本数据的接入

    • +
    • 合约状态上链

    • +
    +
  • +
  • v0.2 2018年10月9日

    +
      +
    • 支持Python包的自动生成

    • +
    • 支持合约打包为ypk

    • +
    • 支持文件、数据库等数据的接入

    • +
    +
  • +
  • v0.1 2018年8月6日

    +
      +
    • 定义了智能合约的语法

    • +
    • 基于nashorn引擎,实现了智能合约的执行

    • +
    +
  • +
+
+
+
+

使用开源项目说明

+

BDWareContract项目站在了许多巨人的肩膀上,感谢这些开源项目。

+

本项目的智能合约后端使用了以下开源库。

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

Licence类型

说明

Project Nashorn

GPLv2

使用了该项目的编译器,可以将js函数编译为java字节码

ASM OW2

BSD with attribution

基于asm的TreeAPI与VisitorAPI实现合约的静态分析框架

Netty

Apache License 2.0

使用netty作为Http/Websocket的服务端

gRPC

Apache License 2.0

使用gRPC与BDWareLedger通讯

RocksDB

GPLv2

后台数据库

ANTLR

BSD

对合约脚本的词法分析与语法分析

SM2Java

国密SM2 Java语言实现

+

本项目的智能合约前端使用了以下开源库。

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

名称

Licence类型

说明

Bootstrap

MIT

前端的排版、样式

jQuery

MIT

用于操作DOM的javascript库

jQueryUI

MIT

前端UI构件库

DataTables

MIT

表格样式

CodeMirror

MIT

代码编辑框样式

eCharts

ApacheV2

统计图表

sm-crypto

MIT

国密SM2 javascript语言实现

+

本项目的文档使用Sphinx生成,感谢readthedocs提供文档样式。

+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/YJSAPI.html b/doc/YJSAPI.html new file mode 100644 index 0000000..0fce47a --- /dev/null +++ b/doc/YJSAPI.html @@ -0,0 +1,2127 @@ + + + + + + + + + + YJS SDK — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

YJS SDK

+
+

YJS Build-in API

+
+

内置对象 Global

+
+
+

内置对象 requester

+

该内置对象在export function里面会有值,仅当合约调用签名验证通过。

+
+
+

执行合约 executeContract

+

参数:

+
action:executeContract;
+contractID:合约的id或名称均可;
+operation:调用合约的方法名;
+arg: 参数;格式为JSON字符串,有action与arg两个字段。
+
+
+

可选参数:

+
requestID:字符串类型,自行生成,用于查询hash
+
+
+

使用示例:

+
function testExecutorContract(arg){
+   var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg));
+   if (ret.status == "Success"){
+     return JSON.parse(ret.result);
+   }else return null;
+ }
+
+
+
+
+

订阅事件主题 subscribe

+

参数

+
contractID:字符串类型 合约id或名称均可。
+event:字符串类型
+handler:方法名,该方法必须接受Event(内含字段topic和content)类型的唯一变量为参数;可以不是export方法
+
+
+

使用示例:

+
export function init(arg) {
+    YancloudUtil.subscribe("topic", handler);
+    print("Handler: " + handler);
+}
+
+function handler(e) {
+    print("topic: " + e.topic);
+    print("content: " + e.content);
+}
+
+
+
+
+

发布事件 pubEvent

+

参数

+
topic:字符串类型,发布的事件主题
+content:字符串类型,发布的事件内容
+
+
+

使用示例:

+
export function pub1(arg) {
+    YancloudUtil.pubEvent("topic", arg);
+    return "done";
+}
+
+
+

也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件

+
event topic;
+export function pub2(arg) {
+    topic(arg);
+    return "done";
+}
+
+
+

该写法与上面的pub1等价。

+
+
+

发布带语义事件 pubEventConstraint

+

参数

+
topic:字符串类型,发布的事件主题
+content:字符串类型,发布的事件内容
+semantics:枚举类型,作为字符串输入,事件语义
+
+
+

事件语义参数 + AT_LEAST_ONCE:至少一次,默认语义 + +AT_MOST_ONCE:至多一次 + ONLY_ONCE:只有一次

+

使用示例:

+
export function pub1(arg) {
+    YancloudUtil.pubEventConstraint("topic", arg, "AT_MOST_ONCE");
+    return "done";
+}
+
+
+

也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名按声明的语义发布事件

+
event AT_MOST_ONCE topic;
+export function pub2(arg) {
+    topic(arg);
+    return "done";
+}
+
+
+

该写法与上面的pub1等价。

+

事先声明的事件无论是否声明语义,都可以用后缀s作为方法名的方式调用,发布任意语义的事件:

+
event topic;
+export function pub3(arg) {
+    topics(arg, "AT_MOST_ONCE");
+    return "done";
+}
+
+
+

该写法与上面的pub1, pub2等价。

+

不带事件语义声明事件时,语义默认为至少一次(AT_LEAST_ONCE)。

+
+
+

访问资源文件

+

通过Global.Resources去加载ypk内部的资源文件。

+
+

loadAsInputStream

+

参数:

+
path:字符串类型 需要加载文件的地址
+
+
+

使用示例:

+
var file = Global.Resources.loadAsInputStream("/deleteit.txt");
+
+
+
+
+

loadAsScanner

+

参数:

+
path:字符串类型 需要加载文件的地址
+
+
+

使用示例:

+
var scanner = Global.Resources.loadAsScanner("/local.txt");
+
+
+
+
+
+
+

YJS Build-in Annotation

+
+

@Access

+

设置合约的调用是否需要签名,这里分为两种,需签名和无签名。 +其中,“verified”表示需要签名。其他则表示无需签名。

+
@Access("verified")
+export function easy(arg){
+    return "true";
+}
+
+
+
+
+

@LogType

+

LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。

+

其中,Arg表示日志中记录合约执行的参数;Result表示记录合约执行的返回结果;Branch表示记录合约执行分支。

+

例如 ,通过如下LogType注解来声明函数

+
@LogType("Arg","Result","Branch")
+export function easy(arg){
+    Global.a = "a";
+    Global.b = "b";
+    if(arg > 0)
+        return Global.a;
+    else
+        return Global.b;
+}
+
+
+
+
+

@LogLocation

+

该注解可以修饰contractfunction。 +设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地,如果没有指定为“dataware”则仅存储在本地。 +例如,通过如下LogLocation设置存储位置。

+

在BaaS平台中,可以指定账本名称,BaaS平台默认账本为default,使用 +@LogLocation("bdledger:default")。如想保存到自定义的账本,比如,“abc”账本,就使用 +@LogLocation("bdledger:abc")

+
@LogLocation("dataware")
+export function easy(arg){
+    Global.a = "a";
+}
+
+
+
+
+

@Permission

+

该注解只能修饰contract +设置合约中调用的工具类的权限,包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类,需要在注解中添加对应的授权字段,默认只有YJS自带的YancloudUtil;如果没有添加则会抛出“未授权工具类”的异常。 +这6种工具类的详细说明在本小节后续中有说明。

+
@Permission("Http","File")
+contract HttpPermission {
+    export function main(args){
+        var http=HttpUtil.httpGet(args);
+        var dir="adf/adfas/";
+        var file=FileUtil.getDir(dir);
+        return YancloudUtil.currentTimeMillis();
+    }
+}
+
+
+
+
+

@Description

+

该注解可以修饰contractfunction。 +传入合约及函数的简介,可用于生成说明文档中关于exported函数的介绍。

+
@Description("返回数据条目,无需参数")
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+

@Param

+

该注解可以修饰function。 +提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。

+
@Param({"offset":0,"count":100})
+export function get(args){
+    var offset = args.offset;
+    var count = args.count;
+    ...
+}
+
+
+
+
+

@MockTemplate

+

该注解可以修饰function。 +提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时,返回按照此格式生成的模拟数据。

+

####支持的字段类型

+
@integer 整数
+@string  字符串
+@boolean 布尔值
+@date @time @datatime
+@word 单词  @cword 中文单词
+@first @last 英文姓,名
+@cfirst @clast @cname 中文姓,名,全名
+@url @domin @ip @email
+@region @province @city @county 地区,省,市,县
+……
+详细格式可以参考http://mockjs.com/examples.html
+
+
+

####注意:模板的格式为{‘result’:模板}

+
//返回一个对象包含如下字段
+@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
+//返回
+{"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"}"
+
+//返回元素个数为1-5个之间的一个数组,数组的每个元素都是上述格式的一个对象
+{'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]}
+//返回
+[
+  {"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"},
+  {"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"},
+  {"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"}
+]
+
+
+
@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+

@Result

+

该注解可以修饰function。 +提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。

+
@Result(666)
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+
+

IO工具类

+
+

概览

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

IO工具类名称

说明

FileUtil

文件操作相关的类

LedgerUtil

账本操作相关的类

HttpUtil

Http接口相关的类

DOIPUtil

DoIP相关的类

MySQLUtil

连接mysql数据库

MongoDBUtil

MongoDB连接相关的类

RocksDBUtil

RocksDB(基于本地文件的k-v数据库)

BDWareTimeSeriesDBUtil

基于本地文件的时间序列数据库

+
+
+

FileUtil

+

可以使用@Permission(“File”)来引入FileUtil对象。

+
@Permission("File")
+contract FileSample {
+...
+}
+
+
+

该对象支持以下方法:

+
+

copyTo

+

可以复制文件和目录。第一个参数是source,第二个参数是destination。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

src

类型为String

2

dest

类型为String

+
+
+
使用示例
+
var ret = FileUtil.copyTo("./source.txt","./dest.txt");
+
+
+
+
+
+

getContent

+

获取文件的文本内容,当文件不存在时,返回undefined

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

path

类型为String

+
+
+
使用示例
+
var ret = FileUtil.getContent("./source.txt");
+
+
+
+
+
+

getDir

+

获取文件所在的文件夹名,输入参数为字符串。

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

path

类型为String

+
+
+
使用示例
+
var ret = FileUtil.getDir("./parent/src.txt");
+// ret 为 "./parent/";
+
+
+
+
+
+

getFileName

+

获取文件名。输入参数为字符串。

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

path

类型为String

+
+
+
使用示例
+
var ret = FileUtil.getFileName("./parent/src.txt");
+// ret 为 "src.txt"
+
+
+
+
+
+

openFileAsPrinter

+

以PrintStream的形式打开文件。 +返回结果是java.io.PrintStream类型。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

path

文件名,类型为String

2

isAppend

类型为boolean,表示是否往文件末尾添加

+
+
+
使用示例
+
var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true);
+ret.println("hello");
+ret.close();
+
+
+
+
+
+
+

LedgerUtil

+

可以使用@Permission(“Ledger”)来引入LedgerUtil对象。

+
@Permission("Ledger")
+contract LedgerExample{
+...
+}
+
+
+
+

getClient

+

获取一个连接客户端,一个参数,为对象类型。 +返回结果为LedgerClient类型,用于后续的查询账本等操作。

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

address

包含ip和端口两个字段

+
+
+
使用示例
+
var address = {};
+address.ip = "127.0.0.1";
+address.port = 18091;
+var ledgerClient = LedgerUtil.getClient(address);
+
+
+
+
+
+

queryByHash

+

根据Hash查询Transaction。 +返回结果为对象,包含from、to、type和data四个字段,均为String类型。 +其中data为按utf-8编码解析字节数组,如果存证时用的不是utf8编码,可能返回乱码。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

client

通过getClient方法获得的对象

2

info

对象类型,有两个字段ledger和hash,均为字符串类型

+
+
+
使用示例
+
// ... ledgerClient = LedgerUtil.getClient(...);
+var info = {};
+info.ledger = "bdcontract";
+info.hash = "4d3b75750835092a50085127702669615b602e53";
+var ret = LedgerUtil.queryByHash(ledgerClient,info);
+print(ret.from);
+print(ret.to);
+print(ret.type);
+print(ret.data);
+
+
+
+
+
+

sendTransaction

+

存证数据。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

client

通过getClient方法获得的对象

2

info

对象类型,有from:raw-latex:to:raw-latex:`\data三个字段`,均为String类型

+
+
+
使用示例
+
// ... ledgerClient = LedgerUtil.getClient(...);
+var info = {};
+info.ledger = "bdcontract";
+info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155";
+info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155";
+info.data = "hello world";
+var ret = LedgerUtil.sendTransaction(ledgerClient,info);
+//ret为存证的哈希值
+print(ret);
+
+
+
+
+
+
+

HttpUtil

+

可以使用@Permission(“Http”)来引入HttpUtil对象。

+
@Permission("Http")
+contract HttpExample{
+...
+}
+
+
+
+

createAPIGate

+

配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

ip

字符串类型,ip,端口默认为6161

+
+
+
使用示例
+
var ret = HttpUtil.createAPIGate("192.168.4.4");
+ret.get("com.tencent.mm","sendMsg","msg");
+print(ret);
+
+
+
+
+
+

createAPIGate

+

配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

ip

字符串类型,ip

2

port

字符串类型,端口

+
+
+
使用示例
+
var ret = HttpUtil.createAPIGate("192.168.4.4", "6161");
+ret.get("com.tencent.mm","sendMsg","msg");
+print(ret);
+
+
+
+
+
+

get

+

发起Http的get请求。 +返回结果为对象类型,包含response和responseCode两个字段。

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

url

字符串,表示url类型

+
+
+
使用示例
+
var ret = HttpUtil.get("https://www.baidu.com");
+print(ret.responseCode);
+print(ret.response);
+
+
+
+
+
+

post

+

发起Http的post请求。 +返回结果为对象类型,包含response和responseCode两个字段。

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

args

对象类型,有url,headers和data三个字段。其中,args.headers为对象类型。

+
+
+
使用示例
+
var req = {};
+req.url = "https://www.baidu.com";
+req.data = "hello";
+req.header = {};
+req.header.Accept = "application/json";
+req.header["Content-Type"] = "application/json";
+var ret = HttpUtil.post(req);
+print(ret.resposeCode);
+print(ret.response);
+
+
+
+
+
+
+

DOIPUtil

+

可以使用@Permission(“DOIP”)来引入DOIPUtil对象。

+
@Permission("DOIP")
+contract DOIPExample{
+  ...
+}
+
+
+
+

call

+

调用一个DO

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型, 目标DO标识

2

arg1

字符串类型, 输入参数字符串

+
+
+
使用示例
+
var ret = DOIPUtil.call("86.5000.470/do.hello","inputString");
+
+
+
+
+
+

create

+

向一个Repository创建一个字符串类型DO

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型, 目标Repo标识

2

arg1

对象类型,包括doID,doBody字段

+
+
+
使用示例
+
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
+var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject);
+
+
+
+
+
+

delete

+

从一个Repository中删除DO

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 目标DO标识

2

arg1

字符串类型 目标Repo标识

+
+
+
使用示例
+
var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo");
+
+
+
+
+
+

hello

+

获取目标Repository的DOIP服务信息

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 目标Repo标识

+
+
+
使用示例
+
var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo");
+
+
+
+
+
+

listOperation

+

获取目标DO支持的DOIP操作

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 目标DO标识

+
+
+
使用示例
+
var ret = DOIPUtil.listOperation("86.5000.470/do.hello");
+
+
+
+
+
+

register

+

向LHS注册一个DO,返回分配的标识

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 DO所在Repo标识

2

arg1

字符串类型 DO格式描述字符串

+
+
+
使用示例
+
var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String");
+
+
+
+
+
+

reregister

+

修改LHS中DO的注册信息

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 目标DO标识

2

arg1

字符串类型 DO所在Repo标识

3

arg2

字符串类型 DO格式描述字符串

+
+
+
使用示例
+
var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String");
+
+
+
+
+
+

retrieve

+

获取一个DO

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 目标DO标识

+
+
+
使用示例
+
var ret = DOIPUtil.retrieve("86.5000.470/do.hello");
+
+
+
+
+
+
+

test

+

测试DOIPUtils是否可用 ##### 参数

+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

arg0

字符串类型 任意字符串

+
var ret = DOIPUtil.test("hello");
+
+
+
+

update

+

更新目标DO

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

arg0

JS对象,包括doID,doBody字段

+
+
+
使用示例
+
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
+var ret = DOIPUtil.update(digitalObject);
+
+
+
+
+
+
+

SQLUtil

+

可以使用@Permission(“SQL”)来引入SQLUtil对象。 +可支持MySQL/PostgreSQL/Oracle/GuassDB200等SQL数据库。 +需要将对应的jdbc的jar上传到项目中。 +例如,要使用mysql,可上传mysql-connector-java-8.0.24.jar

+
@Permission("SQL")
+oracle MySQLExample{
+...
+}
+
+
+
+

initDriver

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

driverClass

字符串类型

+
+
+
使用示例
+
//使用mysql
+SQLUtil.initDriver("com.mysql.cj.jdbc.Driver");
+//使用postgresql
+SQLUtil.initDriver("org.postgresql.Driver");
+//使用oracle
+SQLUtil.initDriver("oracle.jdbc.OracleDriver");
+
+
+
+
+
+

getConnection

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + + + + + +

序号

参数

说明

1

URL

字符串类型,jdbc连接

2

usrName

字符串类型,用户名

3

pwd

字符串类型,密码

+
+
+
使用示例
+
var url = "jdbc:mysql://xx.xx.xx:port/tableName";
+var usrName = "xxx";
+var pwd = "xxx";
+//配置好用户名和密码,url格式为ip或域名+端口,中间以”:”隔开。
+var conn = SQLUtil.getConnection(url,usrName,pwd);
+//获取数据库连接
+var sql = "select * from newele.data";
+//创建查询语句
+var statement = conn.createStatement();
+var resultSet = statement.executeQuery(sql);
+var waimailist  = [];
+//解析查询结果
+var meta = resultSet.getMetaData();
+for (;resultSet.next();){
+  var line = {};
+  for (var j=1;j<=meta.getColumnCount();j++){
+    line[meta.getColumnName(j)] = resultSet.getString(j);
+  }
+    waimailist.push(line);
+}
+
+
+

其中,getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此,可以查看: +https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html +以了解如何进行Mysql数据库操作。

+
+
+
+
+

MongoDBUtil

+

可以使用@Permission(“MongoDB”)来引入MongoDBUtil对象。

+
@Permission("MongoDB")
+contract MongoDBExample{
+...
+}
+
+
+
+

getConnection

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

序号

参数

说明

1

URL

字符串类型 数据库的URL

2

port

整数类型 端口号

3

dbName

字符串类型 数据库的名称

4

usrName

字符串类型 数据库的用户名

5

pwd

字符串类型 数据库的密码

+
+
+
使用示例
+

注意:port为整型,其他参数为String类型

+
var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd);
+//获取数据库对象
+var db = client.getDatabase("yancloud");
+var collection = db.getCollection("containers");
+var iter = collection.find().iterator();
+var ret ="";
+for (;iter.hasNext();){
+    ret+=iter.next().toJson();
+    ret+="\n";
+}
+
+
+

其中,getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此,可以查看: +https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClient.html

+

以了解该对象的更多方法和使用方式。

+
+
+
+
+

RocksDBUtil

+

使用@Permission(“RocksDB”)来引入RocksDBUtil对象。

+
@Permission("RocksDB")
+contract RocksDBSample {
+...
+}
+
+
+
+

loadDB

+

通过loadDB来加载一个RocksDB数据库。 加载后,可进行get/delete/put等操作。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

path

字符串类型 数据库部署的路径

2

readOnly

布尔类型 数据库只读

+
+
+
使用示例
+
@Permission("RocksDB")
+@Description("这是个使用RocksDB的参考代码")
+contract RocksDBSample{
+  function onCreate(){
+    Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false");
+  }
+  @Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}")
+  export function put(arg){
+    arg = JSON.parse(arg);
+    Global.rocksdb.put(arg.key,arg.value);
+    return "success";
+  }
+  @Description("示例参数: \"abc\"}")
+  export function get(arg){
+    return Global.rocksdb.get(arg);
+    return "failed";
+  }
+  @Description("示例参数: \"abc\"")
+  export function deleteKey(arg){
+    return Global.rocksdb.delete(arg);
+  }
+  @Description("遍历KV库,无需参数")
+  export function iter(arg){
+    var iter = Global.rocksdb.newIterator();
+    var obj = undefined;
+    var ret = {
+    };
+    for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){
+      ret[obj.key]=obj.value;
+    }
+    return JSON.stringify(ret)
+  }
+}
+
+
+
+
+
+
+

BDWareTimeSeriesDBUtil

+

使用示例

+
@Permission("BDWareTimeSeriesDB")
+contract BDWareTimeDBExample{
+  function onCreate(arg){
+    Global.dbutil = BDWareTimeSeriesDBUtil.getConnection();
+  }
+
+  export function put(arg){
+    //第一个参数为表名,第二个参数为要放的value,时间戳自动打。
+    Global.dbutil.put("defaultTable",arg);
+    return "success";
+  }
+  @Param
+  export function getCount(arg){
+    return Global.dbutil.getCount("defaultTable");
+  }
+  @Param(1617254937373)
+  export function queryByStartTime(arg){
+    var startDate = java.lang.Long.valueOf(arg);
+    //查询从开始时刻startDate到最新的数据
+    var list = Global.dbutil.query("defaultTable",startDate);
+    var ret=[];
+    print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
+    var i=0;
+    for (i=0;i<list.size();i++){
+      print(i+"-->"+list.get(i));
+      ret.push(list.get(i));
+    }
+    return ret;
+  }
+
+  @Description("示例参数: {\"offset\":1,\"len\":1}")
+  @Param({"offset":1,"len":1})
+  export function queryByOffset(arg){
+    var offsetLen = JSON.parse(arg);
+    //可配合getCount使用,查询第offset至offset+len条数据
+    var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len);
+    var ret=[];
+    print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
+    var i=0;
+    for (i=0;i<list.size();i++){
+      print(i+"-->"+list.get(i));
+      ret.push(list.get(i));
+    }
+    return ret;
+  }
+}
+
+
+
+
+
+

加解密工具类

+
+

SM2

+

可以使用@Permission(“SM2”)来引入SM2Util对象。

+
@Permission("SM2")
+contract SM2Sample {
+...
+}
+
+
+
+

generateKeyPair

+

生成公私钥。

+
+
参数
+

无参数。

+
+
+
使用示例
+
var ret = SM2Util.generateKeyPair();
+print(ret.publicKey);
+print(ret.privateKey);
+return JSON.stringify(ret);
+
+
+
+
+
+

sign

+

签名。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

content

字符串类型 要进行签名的内容

2

keyPair

sm2

+
+
+
使用示例
+
var keypair = SM2Util.generateKeyPair();
+var ret = SM2Util.sign("Hello",keypair);
+print(ret.status);
+//如果status是success
+print(ret.signature);
+//如果status是failed
+print(ret.message);
+
+
+
+
+
+

verify

+

验签。

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + + + + + +

序号

参数

说明

1

content

字符串类型 待验签的内容

2

signature

字符串类型 签名

3

publicKey

字符串类型 公钥

+
+
+
使用示例
+
var ret = SM2Util.verify("Hello","....签名","...公钥");
+// 验证通过时,result为true,status为success
+// 失败时,result为failed,status为failed
+print(ret.status);
+print(ret.result);
+
+
+
+
+
+
+
+

多线程工具类

+
+

AsyncUtil

+

可以使用@Permission(“Async”)来引入AsyncUtil对象。

+
@Permission("Async")
+contract AsyncExample{
+  export function longTimeTask(arg){
+    var a = {
+    };
+    a.count = 100;
+    AsyncUtil.postFunction(taskFun,a);
+  }
+  function taskFun(arg){
+    Global.progress = 0;
+    for (var i=0;i<arg.count;i++){
+      AsyncUtil.sleep(100);
+      Global.progress++;
+    }
+  }
+  export function getProgress(arg){
+    return Global.progress;
+  }
+}
+
+
+
+

postFunction

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

ScriptFunction

2

arg1

对象

+
+
+
使用示例
+
var ret = AsyncUtil.postFunction(a,{"a":"b"});
+
+
+
+
+
+

setInterval

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

ScriptFunction

2

arg1

long

3

arg2

long

4

arg3

对象

+
+
+
使用示例
+
var ret = AsyncUtil.setInterval(a,100,1000,"abc");
+
+
+
+
+
+

setTimeOut

+
+
参数
+ +++++ + + + + + + + + + + + + + + + + + + + + +

序号

参数

说明

1

arg0

ScriptFunction

2

arg1

long

3

arg2

Object

+
+
+
使用示例
+
var ret = AsyncUtil.setTimeOut(a,100,"abc");
+
+
+
+
+
+

sleep

+
+
参数
+ +++++ + + + + + + + + + + + + +

序号

参数

说明

1

arg0

long

+
+
+
使用示例
+
var ret = AsyncUtil.sleep();
+
+
+
+
+
+
+ +
+

YJS应用框架

+
+

加载流程

+

函数约定(getMainFrame)

+
+
+

前端函数说明

+

executeCurrentContract/….. 如何loadScript/loadCss..

+
+
+

后端函数约定

+

getMainFrame

+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/YJSInDepth.html b/doc/YJSInDepth.html new file mode 100644 index 0000000..380fd06 --- /dev/null +++ b/doc/YJSInDepth.html @@ -0,0 +1,500 @@ + + + + + + + + + + YJS语法 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

YJS语法

+
+
+

概述

+

YJS源文件包括任意数量的import声明和一个contract定义

+
+
+
+

import声明

+

与JavaScript(ES6)类似,YJS也支持import声明语句,在全局层面,开发者可以使用如下import声明来导入其他文件。

+
import "filename";
+
+
+
+

内容

+

import声明语句将包含在“filename”文件中的所有全局符号(单元)导入到当前文件,且全局范围内有效。

+
+
+

路径

+

filename通常用/做目录分隔符来表示文件的路径,例如,从同一目录下导入x.yjs文件到当前文件,可以使用import +“x.yjs”语句;从其他目录下导入x.yjs使用import +“lib/x.yjs”语句。

+
+
+
+
+

Contract定义

+
+

示例

+

以下是一个合约示例,用于JSON处理,此YJS源文件以合约名称命名。

+
contract ScoreAdder{
+    //arg =  {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"}
+    export function main(arg){
+        //JSON is a build-in object.
+        var point = JSON.parse(arg);
+        var s = 0;
+        print(point[0].score);
+        print(point.length);
+        for (var i=0;i<point.length;i++){
+            s+=point[i].score/1.0;
+        }
+        print("total score= "+s);
+        return s;
+    }
+}
+
+
+
+
+

注释

+

YJS源文件支持以(//)表示的单行注释和以(/*…*/)表示的多行注释,如下所示:

+
// 这是一个单行注释
+/*
+ * 这是一个
+ * 多行注释
+ */
+
+
+
+
+

注解

+

与Java类似,YJS也支持注解声明合约和函数。

+

在YJS中,有几种内建注解:LogType、LogLocation、Access、Permission。 +当然,可以自定义注解。 +内建注解的详细使用方式可以通过YJS内置API文档查看。 +开发者可以使用如下注解来声明合约和函数。

+
@LogType("Arg","Result","Branch")
+@SelfDefinedAnntation("dad",1)
+@Access
+function xxx(){}
+
+
+
+
+

结构

+

YJS中的合约类似于Java中的类。每个合约都定义了一定数量的变量函数事件

+
+

变量

+

YJS中的变量类似于JavaScript(ES6)中的变量,分为全局变量局部变量

+

全局变量:

+
judge =  true;
+
+
+

局部变量:

+
var vs = "This is a string";
+
+
+

所有的变量都是动态类型,因为变量的具体类型是根据变量值来决定的。如上示例中,全局变量judge是bool类型,局部变量vs是字符串类型。

+
+
+

函数

+

函数是合约中的可执行单元。YJS中有两种类型的函数:普通函数和用export关键字修饰的exported函数。

+

以下是exported函数和普通函数的区别:

+
    +
  1. 只有exported函数能被其他合约调用。

  2. +
  3. exported函数只能有一个参数且参数类型必须为String。

  4. +
  5. exported函数的返回类型必须是String。

  6. +
  7. 内置对象requester(请求者的公钥)只能存在于exported函数或onCreate函数,因为onCreate()虽然没被export关键字修饰,但它自带requester对象且该函数可以自动执行。

  8. +
+
+
+

事件

+

YJS中的事件类似于Solidity中的事件。

+

发布者定义一个包含事件发布函数的事件,然后通过调用事件发布函数发布事件。

+

订阅者订阅并处理事件。

+

事件示例如下:

+

EventPuber.yjs

+
contract EventPuber{
+    event abcEvent;
+    export function pub(arg){
+        abcEvent(arg);
+        return "done!";
+    }
+}
+
+
+

EventSuber.yjs

+
contract EventSuber{
+    export function init(arg){
+        YancloudUtil.subscribe("EventPuber","abcEvent",handler);
+        print("Handler:"+handler);
+    }
+    function handler(e){
+        var ret = "ReceiveEvent:"+(e.type)+" "+(e.content);
+        print(ret);
+    }
+}
+
+
+
+
+
+
+
+

YJS项目

+

除了只包含一个contract定义的YJS源文件,YJS引擎还支持YJS项目

+

每个YJS +project包含了合约执行过程中需用到的各种文件,包括yjs源文件“.yjs”和其他资源文件,如“mainfest.json”, +“.js”, “.txt”,“.jar”, …

+
+

Manifest.json

+

每个YJS项目在项目的根目录下必须有一个mainfest.json文件,此文件描述了合约对于YJS的编译工具(YJS引擎)所需的必要信息。

+
+

Manifest结构

+

manifest文件需包含以下信息:

+
    +
  1. main: 项目中将要被执行的合约文件。

  2. +
  3. type: 合约的类型,如数据合约/算法合约…

  4. +
  5. builder: 构建YJS项目的开发者姓名。

  6. +
  7. insnLimit: 运行合约需要消耗的值。

  8. +
  9. pyDependences: 项目所需的Python依赖。

  10. +
+
+
+

Manifest示例

+
{
+    "main": "contract.js",
+    "type": "Data",
+    "builder": "caihq",
+    "permissions": 0L,
+    "pyDependences": [
+        {
+            "name": "yjsexample",
+            "modules": [
+                {
+                    "name": "sample"
+                }
+            ]
+        }
+    ]
+}
+
+
+
+
+
+

YJS-Java

+

Jar文件实现了YJS与其他编程语言间的跨语言调用,如YJS-Java, +YJS-Python, … +通过将Java文件包成jar包的方式,使得合约可直接调用Java中的方法。

+

Java class:

+
package your.own.pkg;
+public class HelloWorld {
+ public static int fun(String arg){
+  return arg.length;
+ }
+ public int fun2(String arg){
+  return arg.length;
+ }
+}
+
+
+

InvokeJava.yjs

+
contract InvokeJava{
+ export function main(arg){
+  var Hello = Java.type("your.own.package.HelloWorld");
+  var hello = new Hello();
+  return Hello.fun(arg)+hello.fun2(arg);
+ }
+}
+
+
+
+
+

YJS-前端

+

使用数瑞客户端来访问智能合约支持从智能合约中获取html/js/css等资源文件, +并在BDWareWebClient中渲染。 +首先在合约中import以下模块。

+
module Viewable{
+  export function loadResource(arg){
+    return Global.Resources.loadAsString(arg);
+  }
+  export function needRender(arg){
+    return true;
+  }
+}
+
+
+

同时,import以后,定义一个getMainFrame方法,以便数瑞客户端识别主页:

+
export function getMainFrame(arg){
+  return "/html/main.html";
+}
+
+
+

该方法的返回结果为一个资源文件的路径。 +示例的资源文件“/html/main.html”如下:

+
<div>
+<button onclick="queryDataFromContract()">Hello,</button> Data from contract:
+<span id="resultText"></span>
+<script fromContract="/html/hello.js"></script>
+<link fromContract="/html/hello.css"/>
+</div>
+
+
+

示例的资源文件“/html/hello.js”如下:

+
var queryDataFromContract = function(){
+    //第一个参数为函数名,第二个为参数,第三个参数为回调。
+    var data = executeCurrentContract("query","abc",function(argg){
+        $("#resultText")[0].innerHTML = argg.result;
+    });
+}
+
+
+

参考示例:

+
+
+

YJS-Python

+

TODO

+
+
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/_images/analysisExecuteResult.png b/doc/_images/analysisExecuteResult.png new file mode 100644 index 0000000..80b52cd Binary files /dev/null and b/doc/_images/analysisExecuteResult.png differ diff --git a/doc/_images/authMan.jpg b/doc/_images/authMan.jpg new file mode 100644 index 0000000..df1041e Binary files /dev/null and b/doc/_images/authMan.jpg differ diff --git a/doc/_images/authMana.jpg b/doc/_images/authMana.jpg new file mode 100644 index 0000000..1fb6be4 Binary files /dev/null and b/doc/_images/authMana.jpg differ diff --git a/doc/_images/authNodeManager.jpg b/doc/_images/authNodeManager.jpg new file mode 100644 index 0000000..ce63e83 Binary files /dev/null and b/doc/_images/authNodeManager.jpg differ diff --git a/doc/_images/bash-api.png b/doc/_images/bash-api.png new file mode 100644 index 0000000..3d6cc3b Binary files /dev/null and b/doc/_images/bash-api.png differ diff --git a/doc/_images/centerManager.jpg b/doc/_images/centerManager.jpg new file mode 100644 index 0000000..eabae32 Binary files /dev/null and b/doc/_images/centerManager.jpg differ diff --git a/doc/_images/centerNodeList.png b/doc/_images/centerNodeList.png new file mode 100644 index 0000000..e8668f9 Binary files /dev/null and b/doc/_images/centerNodeList.png differ diff --git a/doc/_images/centerNodePage.png b/doc/_images/centerNodePage.png new file mode 100644 index 0000000..07e78d8 Binary files /dev/null and b/doc/_images/centerNodePage.png differ diff --git a/doc/_images/centerNodePreview.png b/doc/_images/centerNodePreview.png new file mode 100644 index 0000000..111c9ea Binary files /dev/null and b/doc/_images/centerNodePreview.png differ diff --git a/doc/_images/centerNodeUnitCreate.png b/doc/_images/centerNodeUnitCreate.png new file mode 100644 index 0000000..314f71e Binary files /dev/null and b/doc/_images/centerNodeUnitCreate.png differ diff --git a/doc/_images/centerNodeUnits.png b/doc/_images/centerNodeUnits.png new file mode 100644 index 0000000..fa7e86d Binary files /dev/null and b/doc/_images/centerNodeUnits.png differ diff --git a/doc/_images/chooseInstance.png b/doc/_images/chooseInstance.png new file mode 100644 index 0000000..dd58914 Binary files /dev/null and b/doc/_images/chooseInstance.png differ diff --git a/doc/_images/closePermission.png b/doc/_images/closePermission.png new file mode 100644 index 0000000..2df7c24 Binary files /dev/null and b/doc/_images/closePermission.png differ diff --git a/doc/_images/codeManage1-1.png b/doc/_images/codeManage1-1.png new file mode 100644 index 0000000..2af24cb Binary files /dev/null and b/doc/_images/codeManage1-1.png differ diff --git a/doc/_images/codeManage1-2.png b/doc/_images/codeManage1-2.png new file mode 100644 index 0000000..57d5727 Binary files /dev/null and b/doc/_images/codeManage1-2.png differ diff --git a/doc/_images/codeManage1.png b/doc/_images/codeManage1.png new file mode 100644 index 0000000..aff2b9a Binary files /dev/null and b/doc/_images/codeManage1.png differ diff --git a/doc/_images/codeManage2.png b/doc/_images/codeManage2.png new file mode 100644 index 0000000..dd4fad0 Binary files /dev/null and b/doc/_images/codeManage2.png differ diff --git a/doc/_images/codeManage3.png b/doc/_images/codeManage3.png new file mode 100644 index 0000000..7676d76 Binary files /dev/null and b/doc/_images/codeManage3.png differ diff --git a/doc/_images/codeManage4.png b/doc/_images/codeManage4.png new file mode 100644 index 0000000..ad0606d Binary files /dev/null and b/doc/_images/codeManage4.png differ diff --git a/doc/_images/codeManage5.png b/doc/_images/codeManage5.png new file mode 100644 index 0000000..8b9c382 Binary files /dev/null and b/doc/_images/codeManage5.png differ diff --git a/doc/_images/codeManage6.png b/doc/_images/codeManage6.png new file mode 100644 index 0000000..03ade62 Binary files /dev/null and b/doc/_images/codeManage6.png differ diff --git a/doc/_images/codeManage7.png b/doc/_images/codeManage7.png new file mode 100644 index 0000000..4a48550 Binary files /dev/null and b/doc/_images/codeManage7.png differ diff --git a/doc/_images/codeManageMenu.png b/doc/_images/codeManageMenu.png new file mode 100644 index 0000000..ddaf7d1 Binary files /dev/null and b/doc/_images/codeManageMenu.png differ diff --git a/doc/_images/config.png b/doc/_images/config.png new file mode 100644 index 0000000..111d0ca Binary files /dev/null and b/doc/_images/config.png differ diff --git a/doc/_images/contract.jpg b/doc/_images/contract.jpg new file mode 100644 index 0000000..a165388 Binary files /dev/null and b/doc/_images/contract.jpg differ diff --git a/doc/_images/contractList.jpg b/doc/_images/contractList.jpg new file mode 100644 index 0000000..6cf8be2 Binary files /dev/null and b/doc/_images/contractList.jpg differ diff --git a/doc/_images/contractLog.jpg b/doc/_images/contractLog.jpg new file mode 100644 index 0000000..de245e6 Binary files /dev/null and b/doc/_images/contractLog.jpg differ diff --git a/doc/_images/contractMode.png b/doc/_images/contractMode.png new file mode 100644 index 0000000..b32397b Binary files /dev/null and b/doc/_images/contractMode.png differ diff --git a/doc/_images/contracteveryLog.jpg b/doc/_images/contracteveryLog.jpg new file mode 100644 index 0000000..65d683b Binary files /dev/null and b/doc/_images/contracteveryLog.jpg differ diff --git a/doc/_images/dashboard.jpg b/doc/_images/dashboard.jpg new file mode 100644 index 0000000..23c862b Binary files /dev/null and b/doc/_images/dashboard.jpg differ diff --git a/doc/_images/deploytopology.png b/doc/_images/deploytopology.png new file mode 100644 index 0000000..c326fac Binary files /dev/null and b/doc/_images/deploytopology.png differ diff --git a/doc/_images/dirstructure.png b/doc/_images/dirstructure.png new file mode 100644 index 0000000..e2c6098 Binary files /dev/null and b/doc/_images/dirstructure.png differ diff --git a/doc/_images/everyLog.jpg b/doc/_images/everyLog.jpg new file mode 100644 index 0000000..fcc7c56 Binary files /dev/null and b/doc/_images/everyLog.jpg differ diff --git a/doc/_images/executeResult.png b/doc/_images/executeResult.png new file mode 100644 index 0000000..21b9e51 Binary files /dev/null and b/doc/_images/executeResult.png differ diff --git a/doc/_images/genReadme.png b/doc/_images/genReadme.png new file mode 100644 index 0000000..dd3347a Binary files /dev/null and b/doc/_images/genReadme.png differ diff --git a/doc/_images/intanceExecute.png b/doc/_images/intanceExecute.png new file mode 100644 index 0000000..bd66b1f Binary files /dev/null and b/doc/_images/intanceExecute.png differ diff --git a/doc/_images/licence.jpg b/doc/_images/licence.jpg new file mode 100644 index 0000000..22010d6 Binary files /dev/null and b/doc/_images/licence.jpg differ diff --git a/doc/_images/log.jpg b/doc/_images/log.jpg new file mode 100644 index 0000000..075d0b0 Binary files /dev/null and b/doc/_images/log.jpg differ diff --git a/doc/_images/log1.png b/doc/_images/log1.png new file mode 100644 index 0000000..04e05a0 Binary files /dev/null and b/doc/_images/log1.png differ diff --git a/doc/_images/log2.png b/doc/_images/log2.png new file mode 100644 index 0000000..33773f7 Binary files /dev/null and b/doc/_images/log2.png differ diff --git a/doc/_images/log3.png b/doc/_images/log3.png new file mode 100644 index 0000000..a2bde90 Binary files /dev/null and b/doc/_images/log3.png differ diff --git a/doc/_images/logMenu.png b/doc/_images/logMenu.png new file mode 100644 index 0000000..9fd8fc5 Binary files /dev/null and b/doc/_images/logMenu.png differ diff --git a/doc/_images/memoryDump.png b/doc/_images/memoryDump.png new file mode 100644 index 0000000..44356a2 Binary files /dev/null and b/doc/_images/memoryDump.png differ diff --git a/doc/_images/node.jpg b/doc/_images/node.jpg new file mode 100644 index 0000000..9827b89 Binary files /dev/null and b/doc/_images/node.jpg differ diff --git a/doc/_images/nodeConfig.png b/doc/_images/nodeConfig.png new file mode 100644 index 0000000..1954dc2 Binary files /dev/null and b/doc/_images/nodeConfig.png differ diff --git a/doc/_images/nodeConfigChange.png b/doc/_images/nodeConfigChange.png new file mode 100644 index 0000000..1f771a9 Binary files /dev/null and b/doc/_images/nodeConfigChange.png differ diff --git a/doc/_images/nodeInfo.jpg b/doc/_images/nodeInfo.jpg new file mode 100644 index 0000000..2282d10 Binary files /dev/null and b/doc/_images/nodeInfo.jpg differ diff --git a/doc/_images/nodeInstancesList.png b/doc/_images/nodeInstancesList.png new file mode 100644 index 0000000..e7e3fd1 Binary files /dev/null and b/doc/_images/nodeInstancesList.png differ diff --git a/doc/_images/nodeInstancesPage.png b/doc/_images/nodeInstancesPage.png new file mode 100644 index 0000000..35e8478 Binary files /dev/null and b/doc/_images/nodeInstancesPage.png differ diff --git a/doc/_images/nodeLicence.png b/doc/_images/nodeLicence.png new file mode 100644 index 0000000..940bab1 Binary files /dev/null and b/doc/_images/nodeLicence.png differ diff --git a/doc/_images/nodeUnits.png b/doc/_images/nodeUnits.png new file mode 100644 index 0000000..502d271 Binary files /dev/null and b/doc/_images/nodeUnits.png differ diff --git a/doc/_images/nodeUserManager.jpg b/doc/_images/nodeUserManager.jpg new file mode 100644 index 0000000..24a4612 Binary files /dev/null and b/doc/_images/nodeUserManager.jpg differ diff --git a/doc/_images/nullPermission.png b/doc/_images/nullPermission.png new file mode 100644 index 0000000..7573bdb Binary files /dev/null and b/doc/_images/nullPermission.png differ diff --git a/doc/_images/opList.jpg b/doc/_images/opList.jpg new file mode 100644 index 0000000..52098d9 Binary files /dev/null and b/doc/_images/opList.jpg differ diff --git a/doc/_images/operator.jpg b/doc/_images/operator.jpg new file mode 100644 index 0000000..9417d67 Binary files /dev/null and b/doc/_images/operator.jpg differ diff --git a/doc/_images/permissionShow.png b/doc/_images/permissionShow.png new file mode 100644 index 0000000..34223df Binary files /dev/null and b/doc/_images/permissionShow.png differ diff --git a/doc/_images/plicence.jpg b/doc/_images/plicence.jpg new file mode 100644 index 0000000..5250e6d Binary files /dev/null and b/doc/_images/plicence.jpg differ diff --git a/doc/_images/roleAuth.jpg b/doc/_images/roleAuth.jpg new file mode 100644 index 0000000..b00e6ce Binary files /dev/null and b/doc/_images/roleAuth.jpg differ diff --git a/doc/_images/set.jpg b/doc/_images/set.jpg new file mode 100644 index 0000000..56ddd88 Binary files /dev/null and b/doc/_images/set.jpg differ diff --git a/doc/_images/updatePermission.png b/doc/_images/updatePermission.png new file mode 100644 index 0000000..7998271 Binary files /dev/null and b/doc/_images/updatePermission.png differ diff --git a/doc/_images/userActive.jpg b/doc/_images/userActive.jpg new file mode 100644 index 0000000..0ea95ac Binary files /dev/null and b/doc/_images/userActive.jpg differ diff --git a/doc/_images/userAll.jpg b/doc/_images/userAll.jpg new file mode 100644 index 0000000..ef58c6d Binary files /dev/null and b/doc/_images/userAll.jpg differ diff --git a/doc/_images/userApplyGraph.jpg b/doc/_images/userApplyGraph.jpg new file mode 100644 index 0000000..343e946 Binary files /dev/null and b/doc/_images/userApplyGraph.jpg differ diff --git a/doc/_images/userList.jpg b/doc/_images/userList.jpg new file mode 100644 index 0000000..927e5fd Binary files /dev/null and b/doc/_images/userList.jpg differ diff --git a/doc/_sources/ContractAPI.rst.txt b/doc/_sources/ContractAPI.rst.txt new file mode 100644 index 0000000..ee612b6 --- /dev/null +++ b/doc/_sources/ContractAPI.rst.txt @@ -0,0 +1,4688 @@ +BDContract SDK +============== + +除使用可视化的智能合约在线IDE外,用户还可使用WebSocket接口、Http接口、Bash接口来启动和运行合约. + +-------------- + +WebSocketSDK下载与安装 +---------------------- + +合约SDK提供javascript版本与java版本的客户端。 + +java客户端的下载链接为:\ `java +source <./_static/BDWareJavaClient.zip>`__\ 和\ `jar <./_static/BDWareConfigTool.zip>`__ +可参考java_source下的README.md及测试用例。 + +javascript的下载链接为:\ `js SDK <./_static/js/createWS.js>`__ +内置的SM2加密库链接:\ `sm2 SDK <./_static/js/sm2.js>`__ + +建立连接 +~~~~~~~~ + +建立与节点服务器之间的WebSocket连接. + +参数 +^^^^ + ++---------+------------------------------------------------------------+ +| 字段 | 值 | ++=========+============================================================+ +| url | 建立WebSocket的服务器URL. 使用\ ``http``\ 协议时, | +| | 前缀为\ ``ws://``, | +| | 如\ ``"ws://localhost:1717/SCIDE/SCExecutor"``; | +| | 使用\ ``https``\ 协议时, 前缀为\ ``wss://`` | ++---------+------------------------------------------------------------+ +| msgHand | 收到服务器WebSocket回复后的回调函数, 用户可自行编写, | +| ler | 也可参考下面提供的示例 | ++---------+------------------------------------------------------------+ + +请求示例 +^^^^^^^^ + +.. code:: javascript + + var url = "ws://127.0.0.1:1717/SCIDE/SCExecutor";//与Slave节点建立连接 + //var url = "ws://127.0.0.1:1718/NodeCenterWS";//与Manager节点建立连接 + var msgHandler = function(m){ + console.log("recmsg:"); + console.log(m); + }; + var onOpenHandler=undefined; + wssocket = createWssocket(url,onOpenHandler,msgHandler); + +返回结果示例 +^^^^^^^^^^^^ + +:: + + { + receiveSeg: [Function (anonymous)], + isSending: false, + sendList: [], + monitor: [Function (anonymous)], + send: [Function (anonymous)], + sendNextSegment: [Function (anonymous)], + isOpen: [Function (anonymous)] + } + +ping +~~~~ + +``ping``\ 服务器测试 + +.. _参数-1: + +参数 +^^^^ + +====== ==== +字段 值 +====== ==== +action ping +====== ==== + +.. _请求示例-1: + +请求示例 +^^^^^^^^ + +:: + + var request = {}; + request.action = "ping"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果示例-1: + +返回结果示例 +^^^^^^^^^^^^ + +:: + + { + "action":"pong" + } + +登录 +~~~~ + +使用Websocket接口调用需要权限的接口时,不论是连接CenterPortal还是NodePortal必须先\ **登录**\ 。 +登录的流程有3步: + +- 客户端向服务端建立连接,连接建立完成后发送{“action”:“getSessionID”}(可在onOpenHandler中实现) +- 服务端收到请求后,会向客户端返回类似{“action”:“onGetSessionID”,“session”:“-4959947809200104526_session”}的结果 +- 客户端收到onGetSessionID后,会使用本地的公私钥对sessionID进行签名,并调用login接口 +- 服务端会返回onLogin的结果,data字段返回的是该公钥对应的角色。 + +-------------- + +用户角色划分 +------------ + +合约节点的角色划分 +~~~~~~~~~~~~~~~~~~ + +在合约节点(NodePortal.html)中分为NodeManager/ContractProvider/ContractInstanceManager/ContractUser四类角色。 + +======================= ========================================================================== +角色 说明 +======================= ========================================================================== +NodeManager 该节点的管理者,拥有用户管理、节点配置等权限 +ContractProvider 拥有编辑合约、开发合约代码、运行调试等权限 +ContractInstanceManager 拥有启、停合约实例、配置合约实例IO等权限 +ContractUser 拥有查看合约实例列表、调用合约等权限 +Anonymous 匿名用户,可以调用合约,可以申请成为ContractProvider/InstanceManager等角色 +======================= ========================================================================== + +=============================== ==================== ========================================= +接口 说明 角色 +=============================== ==================== ========================================= +changeDumpPeriod 设置备份周期 ContractInstanceManager; +createLedger 创建账本 ContractInstanceManager; +dumpContract 手动备份 ContractInstanceManager; +deleteMemoryFile 删除镜像 ContractInstanceManager; +forkContract 迁移合约 ContractInstanceManager; +getDumpPeriod 获取备份周期 ContractInstanceManager; +killAllContract 停止全部实例 ContractInstanceManager; +killContractProcess 停止某一实例 ContractInstanceManager; +listMemoryFiles 列取某一实例的镜像 ContractInstanceManager; +loadMemory 加载镜像 ContractInstanceManager; +queryContractInstanceDOI 查询合约实例信息 ContractInstanceManager; +rebuildHashIndex ContractInstanceManager; +setPermission ContractProvider;ContractInstanceManager; +startContract 启动合约 ContractInstanceManager; +startContractBatched 废弃 ContractInstanceManager; +startContractByYPK 启动合约 ContractInstanceManager; +startContractInTempZips 废弃 ContractInstanceManager; +startContractP2PTrustfully 启动合约(集群模式) ContractInstanceManager; +updateContract ContractInstanceManager; +connectTo 连接合约实例输出流 ContractInstanceManager;ContractUser; +countContractLogGroupByAction ContractInstanceManager;ContractUser; +countContractLogGroupByCategory ContractInstanceManager;ContractUser; +getLastLog 查询日志 ContractInstanceManager;ContractUser; +getLog 查询日志 ContractInstanceManager;ContractUser; +getLogSize 查询日志 ContractInstanceManager;ContractUser; +listAllContractProcess ContractInstanceManager;ContractUser; +listContractProcess 查询合约实例列表 ContractInstanceManager;ContractUser; +listLeakContractProcess ContractInstanceManager;ContractUser; +queryContractLogByDate ContractInstanceManager;ContractUser; +queryContractLogByKey ContractInstanceManager;ContractUser; +queryContractLogByOffset ContractInstanceManager;ContractUser; +queryContractLogDetail ContractInstanceManager;ContractUser; +queryContractLogSize ContractInstanceManager;ContractUser; +queryNodeLogByDate ContractInstanceManager;ContractUser; +queryNodeLogByOffset ContractInstanceManager;ContractUser; +queryNodeLogSize ContractInstanceManager;ContractUser; +rebuildContractLogIndex ContractInstanceManager;ContractUser; +rebuildNodeLogIndex ContractInstanceManager;ContractUser; +changePublic ContractProvider; +createFile 新建文件 ContractProvider; +deleteFile 删除文件 ContractProvider; +distributeContract ContractProvider; +downloadContract ContractProvider; +downloadContractFromOtherHost ContractProvider; +generateAnnotationSample ContractProvider; +generateAppDataAnalysis ContractProvider; +generateAppDataSource ContractProvider; +generateBDCoinEventProject ContractProvider; +generateBDCoinProject ContractProvider; +generateBiddingExample ContractProvider; +generateCSVProject ContractProvider; +generateContractExecutor ContractProvider; +generateDAC4BDOA ContractProvider; +generateDAC4BDOA_persist ContractProvider; +generateDACSample ContractProvider; +generateEmptyProject ContractProvider; +generateEventPublisher ContractProvider; +generateEventSubscriber ContractProvider; +generateGasExample ContractProvider; +generateHello ContractProvider; +generateHttpExample ContractProvider; +generateIncentives ContractProvider; +generateJSONExample ContractProvider; +generateLedgerExample ContractProvider; +generateLedgerProject ContractProvider; +generateLicenceManager ContractProvider; +generateLoggerExample ContractProvider; +generateMySQLExample ContractProvider; +generateMySQLProject ContractProvider; +generatePostgreSQLSample ContractProvider; +generateReadme ContractProvider; +generateRenderSample ContractProvider; +generateRocksDBSample ContractProvider; +generateSM2Example ContractProvider; +generateStaticResource ContractProvider; +generateTFLinux ContractProvider; +generategenerateTFMac ContractProvider; +getProject ContractProvider; +getTemplateList ContractProvider; +importContractInstanceCodeByDOI ContractProvider; +listFile ContractProvider; +listProject ContractProvider; +listProjectPermission ContractProvider; +listProjects ContractProvider; +renameFile ContractProvider; +saveFile ContractProvider; +startContractAsDebug ContractProvider; +uploadFile ContractProvider; +compile ContractProvider;ContractInstanceManager; +evaluates ContractProvider;ContractInstanceManager; +executeContractP2PTrustfully ContractProvider;ContractInstanceManager; +getCodeByID 查询代码 ContractProvider;ContractInstanceManager; +getControlFlowByFileName ContractProvider;ContractInstanceManager; +getGasValue ContractProvider;ContractInstanceManager; +listCompiledFiles ContractProvider;ContractInstanceManager; +queryContractResourceInfo ContractProvider;ContractInstanceManager; +queryFreeResourceInfo ContractProvider;ContractInstanceManager; +staticVerifyContract ContractProvider;ContractInstanceManager; +writeDyjs ContractProvider;ContractInstanceManager; +authNodeRole 授权角色 NodeManager; +changeBDledger 修改账本配置 NodeManager; +changeIpPort NodeManager; +changeNodeCenter 修改集群地址 NodeManager; +changeNodeName NodeManager; +changeIpPort NodeManager; +changeDOIPConfig NodeManager; +changeYJSPath NodeManager; +countNodeLogGroupByCategory NodeManager; +countRole NodeManager; +deleteRole NodeManager; +downloadUUID 废弃 NodeManager; +getEncodedUUID 废弃 NodeManager; +getPeerID NodeManager; +listAllAuthRole NodeManager; +listNodeInfos NodeManager; +listUnAuthRole NodeManager; +loadConfig NodeManager; +loadNodeConfig NodeManager; +lockEdit NodeManager; +unlockEdit NodeManager; +updateConfig NodeManager; +uploadLicence NodeManager; +applyNodeRole 申请角色 任意角色 +executeContract 调用合约 任意角色 +getConnCount 任意角色 +getHashAbstractLocally 任意角色 +getHashLocally 任意角色 +getNodeRoleDeprecated 查询当前角色 任意角色 +getSessionID 任意角色 +listAdapters 任意角色 +listTheContractProcess 任意角色 +login 登录 任意角色 +longStr 任意角色 +ping 任意角色 +queryDataByHash 任意角色 +queryDataByHashLocally 任意角色 +queryHashByOffset 任意角色 +queryHashByRequestID 任意角色 +queryHashSize 任意角色 +queryLedgers 任意角色 +queryRole 任意角色 +queryTransactionByHash 任意角色 +sendTransaction 任意角色 +setLogStage 任意角色 +=============================== ==================== ========================================= + +合约准入中心角色划分 +~~~~~~~~~~~~~~~~~~~~ + +共分为两类角色:CenterManager和NodeManager。其中,CenterManager拥有对集群设置的权限。 +NodeManager可以增加、删除节点等操作。 + +============================= ============ ========================== +接口 说明 角色 +============================= ============ ========================== +authNodeManager CenterManager; +countActionLogByCategory CenterManager; +countCMLogByCategory CenterManager; +delete CenterManager; +listAllUsers CenterManager; +listApplyList CenterManager; +listLicence CenterManager; +queryActionLog CenterManager; +queryCMLog CenterManager; +updateLicence CenterManager; +addNode CenterManager;NodeManager; +changeNCFile CenterManager;NodeManager; +changeOtherNC CenterManager;NodeManager; +createTrustUnit 创建可信集群 CenterManager;NodeManager; +deleteTrustUnit CenterManager;NodeManager; +getNCFile CenterManager;NodeManager; +getNodeTrustUnits CenterManager;NodeManager; +getOtherNC CenterManager;NodeManager; +listContractProcess CenterManager;NodeManager; +listMultiPointContractProcess CenterManager;NodeManager; +listNodes CenterManager;NodeManager; +listTrustUnits CenterManager;NodeManager; +queryUserStat CenterManager;NodeManager; +stopMultiPointContractProcess CenterManager;NodeManager; +applyRole NodeManager; +executeContract 调用合约 任意角色 +executeContractTrustfully 任意角色 +getManagerPubkey 任意角色 +getNodeRole 任意角色 +getNodeSessionID 任意角色 +getRole 任意角色 +getSessionID 任意角色 +login 登录 任意角色 +============================= ============ ========================== + +-------------- + +合约节点Http接口 +---------------- + +``http://xxx.xxx.xxx.xxx:1717/SCIDE/SCManager``\ 为提供Http接口服务的服务器 +URL(\ ``xxx.xxx.xxx.xxx:1717``\ 为BDWare SCIDE运行的IP和端口号) , +用户可通过在URL后附加字段参数, 完成以下功能. +``http://xxx.xxx.xxx.xxx:18000/SCIDE/SCManager`` +为提供Http接口服务的服务器 + +URL(\ ``xxx.xxx.xxx.xxx:1717`` 为BDWare +SCIDE运行的IP和端口号),用户可通过在URL后附加字段参数,完成以下功能: + +用户管理类 +~~~~~~~~~~ + +.. _ping-1: + +ping +^^^^ + +``ping``\ 服务器测试 + +方法 +'''' + +GET + +.. _参数-2: + +参数 +'''' + +====== ==== +字段 值 +====== ==== +action ping +====== ==== + +.. _请求示例-2: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=ping + +.. _返回结果示例-2: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"data":"pong"} + +合约代码管理类 +~~~~~~~~~~~~~~ + +下载合约项目 +^^^^^^^^^^^^ + +.. _方法-1: + +方法 +'''' + +GET + +.. _参数-3: + +参数 +'''' + +=========== ================ +字段 值 +=========== ================ +action downloadContract +projectName 合约项目名 +isPrivate 是否在私有目录下 +pubKey 用户公钥 +timestamp 时间戳 +sign 签名 +=========== ================ + +.. _请求示例-3: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=downloadContract&projectName=BDCoin&isPrivate=false&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3 + 8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275 + +上传文件 +^^^^^^^^ + +.. _方法-2: + +方法 +'''' + +POST + +.. _参数-4: + +参数 +'''' + +========= ================ +字段 值 +========= ================ +path 文件上传路径 +fileName 待上传文件名 +isPrivate 是否在私有目录下 +order 第几个数据包 +count 数据包总数 +timestamp 时间戳 +sign 签名 +========= ================ + +.. _请求示例-4: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/Upload?path=/TEST/TEST.yjs&fileName=WechatIMG15.jpeg&isPrivate=true&order=0&count=3&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05&sign=dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275 + +.. _返回结果示例-3: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"status":"true","data":"success"} + +保存合约脚本 +^^^^^^^^^^^^ + +向服务器发送请求, 向服务器本地保存合约脚本内容. + +.. _方法-3: + +方法 +'''' + +GET + +.. _参数-5: + +参数 +'''' + +======= ============== +字段 值 +======= ============== +action writeDyjs +target 合约脚本文件名 +content 合约脚本内容 +======= ============== + +.. _请求示例-5: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=writeDyjs&target=testyjs.yjs&content=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D + +.. _返回结果示例-4: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "status": false, + "action": "onWriteDyjs", + "data": "success" + } + +后续用户可启动并调用该合约. + +合约实例管理类 +~~~~~~~~~~~~~~ + +查询合约进程 +^^^^^^^^^^^^ + +向服务器发送请求, 查询服务器上已经启动的所有合约进程. + +.. _方法-4: + +方法 +'''' + +GET + +.. _参数-6: + +参数 +'''' + +====== =================== +字段 值 +====== =================== +action listContractProcess +====== =================== + +.. _请求示例-6: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=listContractProcess + +.. _返回结果示例-5: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "status": false, + "action": "onListContractProcess", + "data": "[\n {\n \"id\": \"-562752842\",\n \"name\": \"shortc\",\n \"port\": \"1626\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n }\n]" + } + +启动合约 +^^^^^^^^ + +向服务器发送请求, 启动某个合约. + +.. _方法-5: + +方法 +'''' + +GET + +.. _参数-7: + +参数 +'''' + +====== ================================= +字段 值 +====== ================================= +action startContract +script 合约脚本内容, 需进行进行URIEncode +====== ================================= + +.. _请求示例-7: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=startContract&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D + +.. _返回结果示例-6: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "data": "{\"status\":\"Success\",\"result\":\"\"}", + "action": "onStartContract", + "cid": "-562752842", + "executeTime": 1187 + } + +调用合约 +^^^^^^^^ + +向服务器发送请求, 调用某个合约. + +.. _方法-6: + +方法 +'''' + +GET + +.. _参数-8: + +参数 +'''' + +=================== =========================== +字段 值 +=================== =========================== +action executeContract +contractID 合约ID +withDynamicAnalysis true/false 是否进行动态分析 +operation 调用合约的方法名 +arg 调用合约的参数 +pubkey 可选,调用者公钥 +signature 可选,签名 +=================== =========================== + +其中pubkey为sm2的公钥,计算方式如下: + +.. code:: javascript + + //sm2 可从sm2.js中加载获得。 + signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey); + +.. _请求示例-8: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=executeContract&contractID=-620602333&operation=main&arg=hhh + +.. _返回结果示例-7: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "data": "{\"status\":\"Success\",\"result\":\"3\"}", + "action": "onExecuteResult", + "executeTime": "13" + } + +批量启动合约 +^^^^^^^^^^^^ + +向服务器发送请求, 启动服务器中保存有合约脚本的一系列合约. + +.. _方法-7: + +方法 +'''' + +GET + +.. _参数-9: + +参数 +'''' + +======== ==================================== +字段 值 +======== ==================================== +action startContractBatched +fileList 合约脚本文件列表(Json数组,URLEncode) +======== ==================================== + +.. _请求示例-9: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=startContractBatched&fileList=%5B%20%22EventPuber.yjs%22%2C%20%22EventSuber.yjs%22%2C%20%22LicenceManager.yjs%22%20%5D + +.. _返回结果示例-8: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"EventPuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","LicenceManager.yjs":"{\"status\":\"Success\",\"result\":\"\"}","EventSuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","action":"onStartContract"} + +启动Zip包合约 +^^^^^^^^^^^^^ + +向服务器发送请求, 启动服务器中包装为\ ``zip``\ 格式的合约. + +.. _方法-8: + +方法 +'''' + +GET + +.. _参数-10: + +参数 +'''' + +========= ======================= +字段 值 +========= ======================= +action startContractInTempZips +owner 调用者公钥 +path zip合约(路径及)文件名 +signature 调用者签名 +========= ======================= + +.. _请求示例-10: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=startContractInTempZips&owner=0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55&path=traceTest.zip&signature=650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%2C72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2 + +.. _返回结果示例-9: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"data":"verify failed","action":"onStartContract"} + +获取合约代码 +^^^^^^^^^^^^ + +向服务器发送请求, 获取某个ID合约的脚本代码. + +.. _方法-9: + +方法 +'''' + +GET + +.. _参数-11: + +参数 +'''' + +========== =========== +字段 值 +========== =========== +action getCodeByID +contractID 合约ID +========== =========== + +.. _请求示例-11: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=getCodeByID&contractID=814046805 + +.. _返回结果示例-10: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"status":true,"action":"onCodeResult","data":"@LogType(\"Arg\")\ncontract EventSuberAtCHQ{\n\t\n \texport function init(arg){\n\t\tvar result \u003d YancloudUtil.subscribe(\"EventPuberAt3966\",\"abc\",handler);\n // print(\"Handler:\"+handler);\n \t \n \t\treturn result;\n\t}\n \texport function handler(e){\n var ret \u003d \"ReceiveEvent:\";\n\t\tret+\u003d\"\\n\";\n \tprint(ret);\n \tret+\u003dYancloudUtil.executeContract(\"EventPuberAt3966\",\"notify\",\"success\");\n \tprint(ret);\n return ret;\n\t}\n}\n"} + +保存合约状态 +^^^^^^^^^^^^ + +向服务器发送请求, 获取节点服务器的状态转移日志. + +.. _方法-10: + +方法 +'''' + +GET + +.. _参数-12: + +参数 +'''' + +========== =================== +字段 值 +========== =================== +action dumpContract +contractID 合约ID 或 合约Name= +========== =================== + +.. _请求示例-12: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/SCManager?action=dumpContract&contractID=counter&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83 + +.. _返回结果示例-11: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"data":"success","size":"3.76 KB","time":"0.03s"} + +获取合约内存文件列表 +^^^^^^^^^^^^^^^^^^^^ + +向服务器发送请求, 获取某子文件夹中的所有内存文件列表. + +.. _方法-11: + +方法 +'''' + +GET + +.. _参数-13: + +参数 +'''' + +========== ================== +字段 值 +========== ================== +action listMemoryFiles +contractID 合约Id 或 合约Name +========== ================== + +.. _请求示例-13: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/SCManager?action=listMemoryFiles&contractID=-247468535&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b + +.. _返回结果示例-12: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"data":["2020-09-23.18:40:38","2020-09-24.16:03:41","2020-09-24.16:58:39","2020-09-24.18:25:47","2020-09-24.18:32:37","2020-09-24.20:54:41","2020-09-24.20:57:39","2020-09-24.21:31:07","2020-09-24.21:32:09","2020-09-24.21:36:11","2020-09-28.15:29:15","2020-09-28.20:28:29","2020-09-28.20:39:46","2020-09-28.21:45:31","2020-09-28.21:49:18","2020-09-28.22:27:34","2020-09-28.22:31:09","2020-09-28.22:32:49","2020-10-07.16:51:06","2020-10-07.16:51:23","2020-10-25.21:09:10","2020-12-14.19:06:53","2021-02-02.10:28:56","2021-02-02.10:31:13"],"action":"onListMemoryFiles"} + +停止合约 +^^^^^^^^ + +向服务器发送请求, 停止某个合约. + +.. _方法-12: + +方法 +'''' + +GET + +.. _参数-14: + +参数 +'''' + +=========== =================== +字段 值 +=========== =================== +action killContractProcess +id 合约ID +\*requestID 请求ID, String类型 +=========== =================== + +``*``\ 表示可选参数 + +.. _请求示例-14: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=killContractProcess&id=-1759263594 + +.. _返回结果示例-13: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"status":false,"action":"onListContractProcess","data":"[\n {\n \"id\": \"-65051856\",\n \"name\": \"EventSuber\",\n \"port\": \"1631\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"814046805\",\n \"name\": \"EventSuberAtCHQ\",\n \"port\": \"1630\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"2023975189\",\n \"name\": \"LicenceService\",\n \"port\": \"1632\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"-620602333\",\n \"name\": \"shortc\",\n \"port\": \"1627\",\n \"times\": \"0 \",\n \"traffic\": \"0.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n }\n]"} + +停止所有合约 +^^^^^^^^^^^^ + +向服务器发送请求, 停止服务器上启动的所有合约. + +.. _方法-13: + +方法 +'''' + +GET + +.. _参数-15: + +参数 +'''' + +====== =============== +字段 值 +====== =============== +action killAllContract +====== =============== + +.. _请求示例-15: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=killAllContract + +.. _返回结果示例-14: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"status":false,"action":"onKillAllContract","data":"Kill:7357,7541,7548,7555,7584,7585,7591,7598,7609,7612,8440,8442,8444,8521,"} + +静态分析合约 +^^^^^^^^^^^^ + +向服务器发送请求, 静态分析合约脚本. + +.. _方法-14: + +方法 +'''' + +GET + +.. _参数-16: + +参数 +'''' + +========== ==================== +字段 值 +========== ==================== +action staticVerifyContract +contractid 合约ID +script 请求ID, String类型 +========== ==================== + +.. _请求示例-16: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=staticVerifyContract&contractid=943728900&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D&path=static.yjs + +.. _返回结果示例-15: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"data":"{\"status\":\"Success\",\"result\":\"{\\\"main\\\":\\\"Ret:arg \\\"}\"}","action":"onExecuteResult","cid":"943728900","executeTime":54} + +获取合约静态分析流 +^^^^^^^^^^^^^^^^^^ + +向服务器发送请求, 获取某个合约的静态分析Control Flow. + +.. _方法-15: + +方法 +'''' + +GET + +.. _参数-17: + +参数 +'''' + +====== ======================== +字段 值 +====== ======================== +action getControlFlowByFileName +path 合约ID +====== ======================== + +.. _请求示例-17: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=getControlFlowByFileName&path=EventSuber.yjs + +.. _返回结果示例-16: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"init":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","aload 4","invokedynamic dyn:getProp|getElem|getMethod:YancloudUtil (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B3","stmts":["dup","invokedynamic dyn:getMethod|getProp|getElem:subscribe (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B4","stmts":["swap","ldc XiaomiSmartHomeAtPKU","ldc onAirPurifierModeChange","aload 4","invokedynamic dyn:getProp|getElem|getMethod:handler (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B5","stmts":["invokedynamic dyn:call:\\\u003dYancloudUtil\\,subscribe (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B6","stmts":["\u003dL3\u003d","astore 5"],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B7","stmts":["\u003dL4\u003d","aload 5","areturn"],"original":" \t\treturn result;"},{"type":"Continuous","name":"B8","stmts":["\u003dL5\u003d"],"original":" \t\treturn result;"},{"type":"Continuous","name":"B9","stmts":["\u003dL6\u003d"],"original":" \t\treturn result;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B9","label":{"label":"e"}}]},"handler":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","ldc ReceiveEvent:","aload 2","invokedynamic dyn:getProp|getElem|getMethod:content (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B3","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B4","stmts":["ldc ","invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B5","stmts":["aload 2","invokedynamic dyn:getProp|getElem|getMethod:type (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B6","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B7","stmts":["\u003dL3\u003d","astore 5"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B8","stmts":["\u003dL4\u003d","aload 4","invokedynamic dyn:getMethod|getProp|getElem:print (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":" \tprint(ret);"},{"type":"Continuous","name":"B9","stmts":["getstatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime UNDEFINED Lwrp/jdk/nashorn/internal/runtime/Undefined;","aload 5","invokedynamic dyn:call:print (Ljava/lang/Object;Lwrp/jdk/nashorn/internal/runtime/Undefined;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":" \tprint(ret);"},{"type":"Continuous","name":"B10","stmts":["pop"],"original":" \tprint(ret);"},{"type":"Continuous","name":"B11","stmts":["\u003dL5\u003d","aload 5","areturn"],"original":" return ret;"},{"type":"Continuous","name":"B12","stmts":["\u003dL6\u003d"],"original":" return ret;"},{"type":"Continuous","name":"B13","stmts":["\u003dL7\u003d"],"original":" return ret;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B8","label":{"label":"e"}},{"from":"B8","to":"B9","label":{"label":"e"}},{"from":"B9","to":"B10","label":{"label":"e"}},{"from":"B10","to":"B11","label":{"label":"e"}},{"from":"B11","to":"B13","label":{"label":"e"}}]}} + +日志查看类 +~~~~~~~~~~ + +合约日志-查询数量 +^^^^^^^^^^^^^^^^^ + +.. _方法-16: + +方法 +'''' + +GET + +contractName为空或是不传入时,则为查询全部合约的条数 + +.. _参数-18: + +参数 +'''' + +============ ======================== +字段 值 +============ ======================== +action queryContractLogSize +contractName 字符串,非必须,合约名称 +============ ======================== + +.. _请求示例-18: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogSize&contractName=NanningDataSource + +.. _返回结果示例-17: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "size": 12, + "action": "onQueryContractLogSize", + "status": "success" + } + +合约日志-根据日期查询 +^^^^^^^^^^^^^^^^^^^^^ + +.. _方法-17: + +方法 +'''' + +GET + +.. _参数-19: + +参数 +'''' + +============ ===================================== +字段 值 +============ ===================================== +action queryContractLogByDate +start long,必须,起始时间 +end long,非必须,若无end,默认为当前时间 +contractName 字符串,非必须,合约名称 +============ ===================================== + +.. _请求示例-19: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByDate&start=1597296300272&end=1597296305747 + +返回结果 +'''''''' + +.. code:: json + + { + "data": [ + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getMainFrame", + "costTime": "2493", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296300272, + "key": "-8590335427581967208" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "732", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296301030, + "key": "849660532962309239" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4580", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305745, + "key": "-8003529429500512736" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4551", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305746, + "key": "7604666709899222357" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305751, + "key": "-7561786202695627022" + } + ], + "action": "onQueryRecentContractLog" + } + +合约日志-根据偏移量查询 +^^^^^^^^^^^^^^^^^^^^^^^ + +.. _方法-18: + +方法 +'''' + +GET + +.. _参数-20: + +参数 +'''' + +============ ============================================= +字段 值 +============ ============================================= +action queryContractLogByOffset +count long,必须,获取日志条数 +offset long,非必须,若无offset,默认返回最新count条 +contractName 字符串,非必须,合约名称 +============ ============================================= + +.. _请求示例-20: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByOffset&count=5&contractName=NanningDataSource + +.. _返回结果-1: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [ + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305842, + "key": "-2390672423847654148" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "isOwner", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305868, + "key": "6056586201629372511" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getApplyList", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305893, + "key": "3882409580676458151" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getAcceptList", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305908, + "key": "-3437513873417136535" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "analysisByIndustry", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02", + "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}", + "date": 1597296314654, + "key": "203156239086062402" + } + ], + "action": "onQueryRecentContractLog" + } + +合约日志-根据key查询 +^^^^^^^^^^^^^^^^^^^^ + +.. _方法-19: + +方法 +'''' + +GET + +.. _参数-21: + +参数 +'''' + +====== =========================== +字段 值 +====== =========================== +action queryContractLogByKey +key long,必须,该日志对应的key +====== =========================== + +.. _请求示例-21: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByKey&key=203156239086062402 + +.. _返回结果-2: + +返回结果 +'''''''' + +.. code:: json + + { + "data": { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "analysisByIndustry", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02", + "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}", + "date": 1597296314654 + }, + "action": "onQueryContractLogByKey" + } + +合约日志-按时间段统计调用次数 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _方法-20: + +方法 +'''' + +GET + +.. _参数-22: + +参数 +'''' + +======== ======================================================== +字段 值 +======== ======================================================== +action countContractLogGroupByCategory +start long,必须,起始时间 +end 非必须,终止时间,默认为当前 +interval long,非必须,统计间隔 +category 非必须,合约名称以逗号连接,不传入时统计全部合约调用情况 +======== ======================================================== + +.. _请求示例-22: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=countContractLogGroupByCategory&start=1596758400000&interval=86400000 + +.. _返回结果-3: + +返回结果 +'''''''' + +.. code:: json + + { + "start": 1596758400000, + "interval": 86400000, + "action": "onCountContractLogGroupByCategory", + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 43, + 14 + ] + } + +账本日志-查询数量 +^^^^^^^^^^^^^^^^^ + +查询通过本节点去账本上记录的日志数量 + +.. _方法-21: + +方法 +'''' + +GET + +.. _参数-23: + +参数 +'''' + +============ ================ +字段 值 +============ ================ +action queryHashSize +contractName 非必须,合约名称 +============ ================ + +.. _请求示例-23: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashSize&contractName=NanningDataSource + +.. _返回结果-4: + +返回结果 +'''''''' + +.. code:: json + + { + "count": "2", + "action": "onQueryHashSize" + } + +账本日志-根据偏移量查询 +^^^^^^^^^^^^^^^^^^^^^^^ + +查询x条通过本节点去账本上记录的日志的哈希列表 + +.. _方法-22: + +方法 +'''' + +GET + +.. _参数-24: + +参数 +'''' + +============ =========================================================== +字段 值 +============ =========================================================== +action queryHashByOffset +count 整数,必须,表示条数 +offset 整数,非必须,表示偏移量,不传入offset则默认返回最新count条 +contractName 字符串,非必须,表示合约名称 +============ =========================================================== + +.. _请求示例-24: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashByOffset&count=1&contractName=NanningDataSource + +.. _返回结果-5: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [ + { + "hash": "3a6c60621907146b77146c1f2d48700e47520173", + "date": 1597296314658 + } + ], + "action": "onQueryHash", + "status": "success" + } + +账本日志-根据hash查询详情 +^^^^^^^^^^^^^^^^^^^^^^^^^ + +根据hash来查询日志内容 + +.. _方法-23: + +方法 +'''' + +GET + +.. _参数-25: + +参数 +'''' + +====== =============================== +字段 值 +====== =============================== +action queryDataByHash +hash 字符串,可通过queryHashByOffset +====== =============================== + +.. _请求示例-25: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryDataByHash&count=1&contractName=NanningDataSource&hash=3a6c60621907146b77146c1f2d48700e47520173 + +.. _返回结果-6: + +返回结果 +'''''''' + +.. code:: json + + { + "from": "0x3034643139323433323966373263656431343866", + "to": "0x65786563757465436f6e74726163740000000000", + "data": "1597296314655 --> {\"extraGas\":\"0\",\"totalGas\":\"0\",\"executionGas\":\"0\",\"signature\":\"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02\",\"costTime\":\"6\",\"arg\":\" {\\\\\\\"year\\\\\\\":2018,\\\\\\\"category\\\\\\\":\\\\\\\"工业\\\\\\\",\\\\\\\"indexType\\\\\\\":\\\\\\\"营业额\\\\\\\"}\",\"contractID\":\"-1382208250\",\"action\":\"analysisByIndustry\",\"pubKey\":\"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd\"}", + "requestID": "1597296314629_6067", + "action": "onQueryDataByHash" + } + +账本日志-根据requestID查询Hash +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +根据requestID来查询日志内容,需由开发者保证requestID的唯一性 + +.. _方法-24: + +方法 +'''' + +GET + +.. _参数-26: + +参数 +'''' + +========= ======================== +字段 值 +========= ======================== +action queryHashByRequestID +requestID 字符串,在发起调用时生成 +========= ======================== + +.. _请求示例-26: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=queryHashByRequestID&requestID=0987654321ab + +节点日志-查询数量 +^^^^^^^^^^^^^^^^^ + +.. _方法-25: + +方法 +'''' + +GET + +.. _参数-27: + +参数 +'''' + +======== ============================ +字段 值 +======== ============================ +action queryNodeLogSize +category 非必须,不传入时查询全部情况 +======== ============================ + +其中包括:ping、startContract、saveFile等。 + +.. _请求示例-27: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize&category=login + +.. _返回结果-7: + +返回结果 +'''''''' + +.. code:: json + + { + "size": 177, + "action": "onQueryNodeLogSize", + "status": "success" + } + +节点日志-按日期查询 +^^^^^^^^^^^^^^^^^^^ + +.. _方法-26: + +方法 +'''' + +GET + +.. _参数-28: + +参数 +'''' + +======== ============================ +字段 值 +======== ============================ +action queryNodeLogByDate +start long,必须,起始日期 +end long,非必须 +category 非必须,不传入时查询全部情况 +======== ============================ + +.. _请求示例-28: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1597376006441 + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1596758400000&category=login + +.. _返回结果-8: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [ + { + "action": "listAllAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006438, + "key": "387355870552374748" + }, + { + "action": "listUnAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006441, + "key": "4772693258708933626" + }, + { + "action": "countRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006444, + "key": "-6425375229108830572" + }, + { + "action": "loadNodeConfig", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006448, + "key": "-6602401010405792959" + }, + { + "action": "getPeerID", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006449, + "key": "-7006776427870311552" + } + ], + "action": "onQueryNodeLogByDate" + } + +节点日志-按偏移量查询 +^^^^^^^^^^^^^^^^^^^^^ + +.. _方法-27: + +方法 +'''' + +GET + +.. _参数-29: + +参数 +'''' + +============ ============================================= +字段 值 +============ ============================================= +action queryNodeLogByOffset +count long,必须,获取日志条数 +offset long,非必须,若无offset,默认返回最新count条 +contractName 字符串,非必须,合约名称 +============ ============================================= + +.. _请求示例-29: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByOffset&count=5 + +.. _返回结果-9: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [ + { + "action": "listAllAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006438, + "key": "387355870552374748" + }, + { + "action": "listUnAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006441, + "key": "4772693258708933626" + }, + { + "action": "countRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006444, + "key": "-6425375229108830572" + }, + { + "action": "loadNodeConfig", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006448, + "key": "-6602401010405792959" + }, + { + "action": "getPeerID", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006449, + "key": "-7006776427870311552" + } + ], + "action": "onQueryNodeLogByOffset" + } + +节点日志-按时间段统计调用次数 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _方法-28: + +方法 +'''' + +GET + +.. _参数-30: + +参数 +'''' + +======== ================================================== +字段 值 +======== ================================================== +action countLogGroupByCategory +start long,必须,起始时间 +end 非必须,终止时间,默认为当前 +interval long,非必须,统计间隔 +category 非必须,action以逗号连接,不传入时统计全部调用情况 +======== ================================================== + +其中,category中的action为NodePortal的接口的action集合。 +包括:ping、startContract、saveFile等。 + +.. _请求示例-30: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000 + + http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000&category=ping,startContract + +.. _返回结果-10: + +返回结果 +'''''''' + +.. code:: json + + { + "start": 1596758400000, + "interval": 86400000, + "action": "onCountNodeLogGroupByCategory", + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 912, + 761 + ] + } + +输出历史记录日志 +^^^^^^^^^^^^^^^^ + +向服务器发送请求, 获取节点服务器上合约的TimeTravel日志. + +.. _方法-29: + +方法 +'''' + +GET + +.. _参数-31: + +参数 +'''' + +====== ================== +字段 值 +====== ================== +action printTimeTravelLog +====== ================== + +.. _请求示例-31: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=printTimeTravelLog + +.. _返回结果示例-18: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"status":false,"data":"[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa_1572335939893.dyjs\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n"} + +输出节点转移日志 +^^^^^^^^^^^^^^^^ + +向服务器发送请求, 获取节点服务器的状态转移日志. + +.. _方法-30: + +方法 +'''' + +GET + +.. _参数-32: + +参数 +'''' + +====== ================ +字段 值 +====== ================ +action printTransferLog +====== ================ + +.. _请求示例-32: + +请求示例 +'''''''' + +:: + + http://127.0.0.1:1717/SCIDE/SCManager?action=printTransferLog + +.. _返回结果示例-19: + +返回结果示例 +'''''''''''' + +.. code:: json + + {"status":false,"data":""} + +模板生成类 +~~~~~~~~~~ + +-------------- + +合约节点WebSocket接口 +--------------------- + +.. _用户管理类-1: + +用户管理类 +~~~~~~~~~~ + +获取Session +^^^^^^^^^^^ + +登录前获取session以便进行签名。 + +.. _参数-33: + +参数 +'''' + +====== ============ +字段 值 +====== ============ +action getSessionID +====== ============ + +.. _请求示例-33: + +请求示例 +'''''''' + +:: + + var req = {}; + req.action = "getSessionID"; + wssocket.send(JSON.stringify(req)); + +.. _返回结果-11: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onSessionID", + "session": "9782323_session" + } + +用户登录 +^^^^^^^^ + +用户进行公私钥身份验证 + +.. _参数-34: + +参数 +'''' + +====== ===== +字段 值 +====== ===== +action login +====== ===== + +.. _请求示例-34: + +请求示例 +'''''''' + +:: + + var loginParam = {}; + loginParam.pubKey = global.sm2Key.publicKey; + loginParam.signature = sm2.doSignature(global.session, + global.sm2Key.privateKey); + loginParam.action = "login"; + wssocket.send(JSON.stringify(loginParam)); + +.. _返回结果-12: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onLogin", + "data": "NodeManager,ContractProvider" + } + +申请角色 +^^^^^^^^ + +在节点管理员界面申请可以申请称为合约管理员(ContractInstanceManager)、合约使用者(ContractUser)、合约提供者(ContractProvider) + +.. _参数-35: + +参数 +'''' + +====== ============= +字段 值 +====== ============= +action applyNodeRole +role 申请角色名称 +====== ============= + +.. _请求示例-35: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "applyNodeRole"; + param.role = "ContractUser"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-13: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onApplyRole", + "data": "success" + } + + { + "action":"onApplyRole", + "data":"already has!" + } + +授权角色 +^^^^^^^^ + +.. _参数-36: + +参数 +'''' + +======== ==================== +字段 值 +======== ==================== +action authNodeRole +isAccept bool类型,表示否授权 +pubKey 授权用户公钥 +======== ==================== + +.. _请求示例-36: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "authNodeRole"; + param.isAccept = true; + param.pubKey = "xxxxx"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-14: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onAuthNodeRole", + "data": "success" + } + +删除用户角色 +^^^^^^^^^^^^ + +.. _参数-37: + +参数 +'''' + +====== ============ +字段 值 +====== ============ +action deleteRole +role 删除角色名称 +====== ============ + +.. _请求示例-37: + +请求示例 +'''''''' + +:: + + var deleteInfo = {}; + deleteInfo.pubKey = global.authorizedUsers.[publicKey]; + deleteInfo.action = "deleteRole"; + deleteInfo.role="ContractUser"; + wssocket.send(JSON.stringify(deleteInfo)); + +.. _返回结果-15: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onDeleteRole", + "data": "success" + } + +查看授权用户列表 +^^^^^^^^^^^^^^^^ + +查看准入管理员当前组网中已经授权的节点管理员 + +.. _参数-38: + +参数 +'''' + +====== =============== +字段 值 +====== =============== +action listAllAuthRole +====== =============== + +.. _请求示例-38: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "listAllAuthRole"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-16: + +返回结果 +'''''''' + +.. code:: json + + { + "status":false, + "action":"onListAllAuthRole", + "data": + { + "kv":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab", + "value":"NodeManager,ContractProvider,ContractUser,ContractInstanceManager"}], + "time":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab", + "value":"1617178709933"}] + } + } + +查看申请用户列表 +^^^^^^^^^^^^^^^^ + +.. _参数-39: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action listUnAuthRole +====== ============== + +.. _请求示例-39: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "listUnAuthRole"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-17: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onListUnAuthRole", + "kv": [{ + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": "ContractProvider,ContractUser" + }], + "time": [{ + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": "1587398989914" + }] + } + +参数(删除) +'''''''''' + +====== ============= +字段 值 +====== ============= +action queryUserStat +====== ============= + +.. _请求示例-40: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "queryUserStat"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-18: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onQueryUserStat", + "userListCount": 3, + "applyListCount":0 + } + +.. _合约代码管理类-1: + +合约代码管理类 +~~~~~~~~~~~~~~ + +获取公共合约文件列表 +^^^^^^^^^^^^^^^^^^^^ + +.. _参数-40: + +参数 +'''' + +====== ============ +字段 值 +====== ============ +action listProjects +====== ============ + +.. _请求示例-41: + +请求示例 +'''''''' + +:: + + var request = {}; + request.action = "listProjects"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-19: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onListProjects", + "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\",\"BiddingExample\",\"ContractExecutor\"]", + "executeTime":0, + "isPrivate":false + } + +获取私有合约文件列表 +^^^^^^^^^^^^^^^^^^^^ + +.. _参数-41: + +参数 +'''' + +========= ============ +字段 值 +========= ============ +action listProjects +pubKey 该用户的公钥 +isPrivate true +========= ============ + +.. _请求示例-42: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "listProjects"; + request.pubKey = "global.sm2.publicKey"; + request.isPrivate=true; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-20: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true + } + +获取合约实例 +^^^^^^^^^^^^ + +.. _参数-42: + +参数 +'''' + +====== =================== +字段 值 +====== =================== +action listContractProcess +====== =================== + +.. _请求示例-43: + +请求示例 +'''''''' + +:: + + var request = {}; + request.action = "listContractProcess"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-21: + +返回结果 +'''''''' + +.. code:: json + + { + "status":false, + "action":"onListContractProcess", + "data":"[{\"id\": \"1658407837\",\"name\": \"BDCoin\",\"port\": \"1617\"}]" + } + +.. _启动合约-1: + +启动合约 +^^^^^^^^ + +.. _参数-43: + +参数 +'''' + +========= ============= +字段 值 +========= ============= +action startContract +owner pubkey +requestID 当前时间 +script 脚本内容 +signature 签名 +========= ============= + +.. _请求示例-44: + +请求示例 +'''''''' + +:: + + request.action = "startContract"; + request.owner = global.sm2Key.publicKey; + request.requestID = new Date().getTime() + ""; + request.script = global.projectScript; + request.signature = sm2.doSignature("Algorithm|" + request.script + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey); + wssocket.send(JSON.stringify(request)); + +.. _返回结果-22: + +返回结果 +'''''''' + +.. code:: json + + { + "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":\"\",\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}", + "action":"onStartContract", + "cid":"-506393888", + "executeTime":2496, + "responseID":"1617206735696" + } + +启动可信集群合约 +^^^^^^^^^^^^^^^^ + +.. _参数-44: + +参数 +'''' + +========= ==================================== +字段 值 +========= ==================================== +action startContractP2PTrustfully +owner pubkey +isPrivate 当前时间 +path 脚本所在路径 +signature 签名 +peersID 可信执行集群中的节点peerID组成的数组 +\ +========= ==================================== + +.. _请求示例-45: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "startContractP2PTrustfully"; + request.peersID = ["3r729hf2ehf982","sjdfiwoehfwoi34","wnfnwoeifnwenef"]; + var project = "JsonTest"; + request.path = "/" + project + "/mainfest.json"; + request.isPrivate = false; + request.signature = sm2.doSignature("Trusted|" + request.path + "|" + + global.sm2Key.publicKey, global.sm2Key.privateKey); //合约的签名 + request.resultcheck = $("#resultcheck")[0].value; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-23: + +返回结果 +'''''''' + +.. code:: json + + { + "data":"{\"status\":\"Success\",\"result\":\"\"}", + "action":"onStartContractP2PTrustfully", + "cid":"-1543583350", + "executeTime":1544 + } + +分发合约项目 +^^^^^^^^^^^^ + +.. _参数-45: + +参数 +'''' + +============= ================== +字段 值 +============= ================== +action distributeContract +peersID 集群中节点peer +projectName 合约名 +isPrivate 是否在私有目录 +sponsorPeerID 发起者ID +signature 签名 +============= ================== + +.. _请求示例-46: + +请求示例 +'''''''' + +.. code:: javascript + + request.action = "distributeContract"; + request.peersID = peersID; + request.projectName = global.projects[global.lastClickedProjectId]; + request.isPrivate = $("#privateDir-tab").hasClass("active"); + request.sponsorPeerID = global.peerID; + request.signature = sm2.doSignature("DistributeContract|" + request.projectName + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey); + wssocket.send(JSON.stringify(request)); + +.. _返回结果-24: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onDistributeContract", + "progress":"100.00%" + } + +终止合约 +^^^^^^^^ + +.. _参数-46: + +参数 +'''' + +========= =================== +字段 值 +========= =================== +action killContractProcess +id 合约id +requestID 请求ID +========= =================== + +.. _请求示例-47: + +请求示例 +'''''''' + +:: + + request.action = "killContractProcess"; + request.id = contractid; + request.requestID = new Date().getTime() + ""; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-25: + +返回结果 +'''''''' + +.. code:: json + + { + "data": "ContractHandler: exit in 3 seconds!", + "action": "onOutputStream" + } + +终止所有合约 +^^^^^^^^^^^^ + +.. _参数-47: + +参数 +'''' + +====== =============== +字段 值 +====== =============== +action killAllContract +====== =============== + +.. _请求示例-48: + +请求示例 +'''''''' + +:: + + request.action = "killAllContract"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-26: + +返回结果 +'''''''' + +.. code:: json + + { + "status":false, + "action":"onKillAllContract", + "data":"Kill:7241,7245," + } + +.. _静态分析合约-1: + +静态分析合约 +^^^^^^^^^^^^ + +.. _参数-48: + +参数 +'''' + +========== ==================== +字段 值 +========== ==================== +action staticVerifyContract +owner 用户私钥 +isPartial 是否是部分 +contractid contractid +script 脚本内容 +path 合约文件名 +========== ==================== + +.. _请求示例-49: + +请求示例 +'''''''' + +.. code:: javascript + + request.action = "staticVerifyContract"; + request.owner = global.sm2Key.privateKey + request.isPartial = false; + request.contractid = contractid; + request.script = global.projectScript; + request.path = global.projectName; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-27: + +返回结果 +'''''''' + +.. code:: json + + + { + "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":{\"hello\":\"Ret:\"},\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}", + "action":"onStaticVerifyResult", + "cid":"verify", + "executeTime":83 + } + +删除合约 +^^^^^^^^ + +.. _参数-49: + +参数 +'''' + +====== ========== +字段 值 +====== ========== +action deleteFile +file fileName +====== ========== + +.. _请求示例-50: + +请求示例 +'''''''' + +.. code:: javascript + + request.action = "deleteFile"; + request.file = fileName; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-28: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onDeleteFile", + "data":"success", + "executeTime":0 + } + +私有合约传至公共目录 +^^^^^^^^^^^^^^^^^^^^ + +.. _参数-50: + +参数 +'''' + +======== ============ +字段 值 +======== ============ +action changePublic +pubkey 用户公钥 +fileName fileName +======== ============ + +.. _请求示例-51: + +请求示例 +'''''''' + +.. code:: javascript + + request.action = "changePublic"; + request.pubkey = pubkey; + request.fileName = fileName; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-29: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onChangePublic", + "data":"success", + "executeTime":0 + } + +上传合约 +^^^^^^^^ + +.. _参数-51: + +参数 +'''' + +========= ======================== +字段 值 +========= ======================== +action UploadFile +isAppend false +fileName fileName +path path +isPrivate true/false +content fileContent(base64编码) +========= ======================== + +.. _请求示例-52: + +请求示例 +'''''''' + +:: + + request.action = "uploadFile"; + request.isAppend = false; + request.fileName = "test1.yjs"; + request.path = "test1"; + text="Y29udHJhY3QgdGVzdDF7CglleHBvcnQgZnVuY3Rpb24gaGVsbG8oYXJnKXsgCiAgICAgICAgcmV0dXJuICJ3b3JsZCI7ICAKICAgIH0gICAKfQ==" + request.content = text; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-30: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onUploadFile", + "data":"success", + "executeTime":0 + } + +编译合约 +^^^^^^^^ + +.. _参数-52: + +参数 +'''' + +========== ========================== +字段 值 +========== ========================== +action compile +path string, 待编译的项目名称 +privateTab bool, 是否为私有目录的项目 +========== ========================== + +.. _请求示例-53: + +请求示例 +'''''''' + +.. code:: javascript + + var req = {"action":"compile","path":"Hello","privateTab":true} + +.. _返回结果-31: + +返回结果 +'''''''' + +.. code:: json + + {"result":"Hello_2020-08-17-09:09:40.ypk","action":"onCompile"} + +锁定私有目录 +^^^^^^^^^^^^ + +锁定某个用户的的私有目录编辑功能 + +.. _参数-53: + +参数 +'''' + +====== ====================== +字段 值 +====== ====================== +action lockEdit +pubKey string, 要被锁定的公钥 +====== ====================== + +.. _请求示例-54: + +请求示例 +'''''''' + +.. code:: javascript + + var req = {}; + req.action = "lockEdit"; + req.pubKey = "xxxxxx"; + wssocket.send(JSON.stringify(req)); + +.. code:: json + + { + "action":"onLockEdit", + "status":"success", + "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1" + } + +解锁私有目录 +^^^^^^^^^^^^ + +解锁某个用户的的私有目录编辑功能 + +.. _参数-54: + +参数 +'''' + +====== ====================== +字段 值 +====== ====================== +action unLockEdit +pubKey string, 要被锁定的公钥 +====== ====================== + +.. _请求示例-55: + +请求示例 +'''''''' + +.. code:: javascript + + var req = {}; + req.action = unlockEdit; + req.pubKey = "xxxxxx"; + wssocket.send(JSON.stringify(req)); + +.. code:: json + + { + "action":"onUnlockEdit", + "status":"success", + "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1" + } + +.. _合约实例管理类-1: + +合约实例管理类 +~~~~~~~~~~~~~~ + +.. _查询合约进程-1: + +查询合约进程 +^^^^^^^^^^^^ + +向服务器发送请求, 查询服务器上已经启动的所有合约进程. + +.. _参数-55: + +参数 +'''' + +====== =================== +字段 值 +====== =================== +action listContractProcess +====== =================== + +.. _请求示例-56: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "listContractProcess"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果示例-20: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "status": false, + "action": "onListContractProcess", + "data": "[...]" + } + +.. _调用合约-1: + +调用合约 +^^^^^^^^ + +向服务器发送请求, 调用某个合约. + +.. _参数-56: + +参数 +'''' + +=================== ================================ +字段 值 +=================== ================================ +action executeContract +contractID 合约ID +withDynamicAnalysis true/false 是否进行动态分析,可选 +operation 调用合约的方法名 +arg 调用合约的参数 +pubkey 调用者公钥,可选 +signature 调用者签名 ,可选 +=================== ================================ + +``*``\ 表示可选参数 + +.. code:: javascript + + //sm2 可从sm2.js中加载获得。 + signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey); + +.. _请求示例-57: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "executeContract"; + request.contractID = "2073401446"; + request.operation = "main"; + request.arg = "hhhhh"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果示例-21: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "needSeq":false, + "seq":0, + "status":"Success", + "result":"world", + "isInsnLimit":false, + "totalGas":0, + "executionGas":0, + "extraGas":0, + "size":0, + "eventRelated":false, + "responseID":"1617211077264_223", + "action":"onExecuteResult", + "executeTime":"5" + } + +输出历史记录日志(删除) +^^^^^^^^^^^^^^^^^^^^^^ + +向服务器发送请求, 获取节点服务器上合约的TimeTravel日志. + +.. _参数-57: + +参数 +'''' + +====== ================== +字段 值 +====== ================== +action printTimeTravelLog +====== ================== + +.. _请求示例-58: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "printTimeTravelLog"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果示例-22: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "status": false, + "data": "[CMActions] dumpContract :…t/contractExamples/memoryDumps/LicenceManager\n" + } + +输出节点转移日志(删除) +^^^^^^^^^^^^^^^^^^^^^^^^ + +向服务器发送请求, 获取节点服务器的状态转移日志. + +.. _参数-58: + +参数 +'''' + +====== ================ +字段 值 +====== ================ +action printTransferLog +====== ================ + +.. _请求示例-59: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "printTransferLog"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果示例-23: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "status": false, + "data": "" + } + +合约状态迁移 +^^^^^^^^^^^^ + +向服务器发送请求, 获取节点服务器的状态转移日志. + +.. _参数-59: + +参数 +'''' + +============ ============ +字段 值 +============ ============ +action loadMemory +contractName 合约名称 +memoryFile 合约文件名称 +============ ============ + +.. _请求示例-60: + +请求示例 +'''''''' + +.. code:: javascript + + var request = {}; + request.action = "loadMemory"; + request.contractName = "JsonContract"; + request.memoryFile = "2020-03-17.20/42/55"; + wssocket.send(JSON.stringify(request)); + +.. _返回结果示例-24: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "data":"success", + "size":"0.00 B", + "action":"onTransferTo", + "time":"0.01s" + } + +.. _日志查看类-1: + +日志查看类 +~~~~~~~~~~ + +查看本地近n日节点日志(删除) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _参数-60: + +参数 +'''' + +====== ================ +字段 值 +====== ================ +action listLocalNodeLog +date 当前时间 +====== ================ + +.. _请求示例-61: + +请求示例 +'''''''' + +:: + + request.action = "listLocalNodeLog"; + request.date = new Date().getTime() - 24 * 3600 * 1000 * n; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-32: + +返回结果 +'''''''' + +.. code:: json + + { + "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]" + } + +查看本地近n日合约日志(删除) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _参数-61: + +参数 +'''' + +====== ==================== +字段 值 +====== ==================== +action listLocalContractLog +date 当前时间 +====== ==================== + +.. _请求示例-62: + +请求示例 +'''''''' + +:: + + request.action = "listLocalContractLog"; + request.date = new Date().getTime() - 24 * 3600 * 1000 * n; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-33: + +返回结果 +'''''''' + +.. code:: json + + { + "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]" + } + +节点配置类 +~~~~~~~~~~ + +获取节点配置信息 +^^^^^^^^^^^^^^^^ + +.. _参数-62: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action loadNodeConfig +====== ============== + +.. _请求示例-63: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "loadNodeConfig"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-34: + +返回结果 +'''''''' + +:: + + { + "status": true, + "action": "onLoadNodeConfig", + "data": { + "nodeName": "04BF52213343C147E631B877BCEB17B794230EE551E85F58FA429C4BA03D690778CC384C6916C63DF36CB9E35C7E274FDB4E18491DFE3D611D347856D441CACC5AF9090B515F02AFC2DFBF56461EC83B5A4CD342466360D6CF82E6E40B637430AC4A329CCBC798DAF7D526AF9E3B3600E0BEA1BFAB8C160EF90128FAF67B19E45F37664F1E4B", + "licence": "04AADCC7103CD02626D228AFFBEF53F8242ECA4DDD6F179D30B622440666715CFBB6FD1D3678A2B25812DEA9917073E79A65F7ADE517F784DC76288EFCEB37ECAA1025E6903540702F729DA1C2ECCD93F4E6FAFCE40DF443E7FD74387169D0C6D927C7BB12882D0471C8D3E6F31B0316A42FC38F6DD9978D4351B23B2AD63E2244909E98F51185D32CB99B4AE4E22D3AB4C04027BB", + "expireTime": "Wed Aug 26 09:43:08 CST 2020", + "nodes": "[\"node1\",\"node2\",\"node3\"]", + "yjsPath": "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar", + "nodeCenter": "ws://127.0.0.1:1719/SCIDE/NodeCenter" + } + } + + { + "status":true, + "action":"onLoadNodeConfig", + "data":{ + "nodeName":"Node_180", + "peerID":"", + "masterAddress":"39.104.201.40:21031", + "licence":"04AADCC7103C", + "doipConfig":"{\\"LHSProxyAddress\\":\\"http://39.104.201.40:21042/\\",\\"ownerHandle\\":\\"86.5000.470/dou.TEST\\",\\"certPath\\":\\"keys/dou.TEST.keystore\\",\\"certPassword\\":\\"123456\\",\\"repoID\\":\\"86.5000.470/doip.vcg9Mu1gSq_bdw\\",\\"listeners\\":\\"[{\\\\\\"url\\\\\\":\\\\\\"tcp://39.104.201.40:21032\\\\\\",\\\\\\"protocolVersion\\\\\\":\\\\\\"2.1\\\\\\",\\\\\\"messageFormat\\\\\\":\\\\\\"packet\\\\\\"}]\\",\\"serviceDescription\\":\\"test local Contract Repository\\",\\"serviceName\\":\\"ContractEngine021\\"}", + "clusterConnected":"false", + "nodePubKey":"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5", + "ipPort":"", + "bdledger":"39.108.56.240:18091,39.108.56.12:1809139.104.70.160:18091 47.98.247.70:18091 47.98.248.208:18091 39.104.77.165:18091 47.98.249.131:18091", + "yjsPath":"/data/bdwaas/bdcontract/yjs.jar", + "nodeCenter":"ws://39.104.201.21040/SCIDE/NodeCenter" + } + } + +修改节点配置 +^^^^^^^^^^^^ + +.. _参数-63: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action updateConfig +key 要改的配置项 +val 要更改的目标值 +====== ============== + +其中,key的可选项包括: + +============= =================================== =============================== +key的示 val示例 说明 +============= =================================== =============================== +yjsPath /User/xxx/cp/yjs.jar 合约进程启动所需的jar +dataChain 192.168.1.8:18090,182.173.2.3:18091 账本节点的ip与端口 +nodeCenter ws://127.0.0.1:18002 CenterPortal所在的ip/端口 +nodeName Node_180 字符串类型 +masterAddress 192.168.3.2:18001 该NodePortal节点的ip和的TCP端口 +============= =================================== =============================== + +其中NodePortal的TCP端口为Node的http/ws端口号+1。 + +修改节点名称 +^^^^^^^^^^^^ + +.. _参数-64: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action changeNodeName +data 新的节点名称 +====== ============== + +.. _请求示例-64: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "changeNodeName"; + param.data = "NewNodeName"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-35: + +返回结果 +'''''''' + +.. code:: json + + { + "status": true, + "action": "onChangeNodeName", + "data": true + } + +修改节点YJS路径 +^^^^^^^^^^^^^^^ + +.. _参数-65: + +参数 +'''' + +====== ===================== +字段 值 +====== ===================== +action changeYJSPath +data 节点服务器yjs.jar路径 +====== ===================== + +.. _请求示例-65: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "changeYJSPath"; + param.data = "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-36: + +返回结果 +'''''''' + +.. code:: json + + { + "status": true, + "action": "onChangeYJSPath", + "data": true + } + +修改NodeCenter +^^^^^^^^^^^^^^ + +.. _参数-66: + +参数 +'''' + +====== ========================================= +字段 值 +====== ========================================= +action changeNodeCenter +data 节点服务器要连接的NodeCenterWebSocket路径 +====== ========================================= + +.. _请求示例-66: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "changeNodeCenter"; + param.data = "ws://127.0.0.1:1719/SCIDE/NodeCenter"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-37: + +返回结果 +'''''''' + +.. code:: json + + { + "status": true, + "action": "onChangeNodeCenter", + "data": true + } + +修改账本节点 +^^^^^^^^^^^^ + +.. _参数-67: + +参数 +'''' + +====== =========================== +字段 值 +====== =========================== +action changeBDledger +data 数链节点的IP:port,用“,”隔开 +====== =========================== + +.. _请求示例-67: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "changeBDledger"; + param.data = "39.108.56.240:18091,39.108.56.12:18091"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-38: + +返回结果 +'''''''' + +.. code:: json + + { + "status": true, + "action": "onChangeBDledger", + "data": true + } + +上传节点Licence +^^^^^^^^^^^^^^^ + +.. _参数-68: + +参数 +'''' + +====== ======================= +字段 值 +====== ======================= +action uploadLicence +data 节点服务器的Licence内容 +====== ======================= + +.. _请求示例-68: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "uploadLicence"; + param.data = "04AADCC7103C"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-39: + +返回结果 +'''''''' + +.. code:: json + + { + "status": true, + "action": "onUploadLicence", + "data": true + } + +获取节点ID +^^^^^^^^^^ + +.. _参数-69: + +参数 +'''' + +====== ========= +字段 值 +====== ========= +action getNodeID +====== ========= + +.. _请求示例-69: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "getNodeID"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-40: + +返回结果 +'''''''' + +.. code:: json + + { + "status": true, + "action": "onGetNodeID", + "data": "0431…d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d" + } + +获取节点所在的可信执行集群 +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _参数-70: + +参数 +'''' + +========== ================================================ +字段 值 +========== ================================================ +action getNodeTrustUnits +data 节点ID +msgHandler 收到回复的回调函数, 可使用“建立连接”的msgHandler +ws 节点所属的NodeCenter的WebSocket地址 +========== ================================================ + +.. _请求示例-70: + +请求示例 +'''''''' + +:: + + centerportalws = createWssocket("ws://127.0.0.1:1718/NodeCenterWS",function() { + var param = {}; + param.action = "getNodeTrustUnits"; + param.data = "0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d"; + centerportalws.send(JSON.stringify(param)); + }, msgHandler); + +.. _返回结果-41: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [{ + "key": "0475c7b061...65e55_4063665700873624164", + "value": "[\"04541429c11b094…40009b4f06d\"]" + }], + "action": "onGetNodeTrustUnits" + } + +.. _模板生成类-1: + +模板生成类 +~~~~~~~~~~ + +获取合约模板列表 +^^^^^^^^^^^^^^^^ + +.. _参数-71: + +参数 +'''' + +====== =============== +字段 值 +====== =============== +action getTemplateList +====== =============== + +.. _请求示例-71: + +请求示例 +'''''''' + +.. code:: javascript + + req={}; + req.action = "getTemplateList"; + wssocket.send(JSON.stringify(req)); + +.. _返回结果-42: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [ + { + "formDesc": { + "dbPWD": { + "label": "密码", + "type": "input" + }, + "contractName": { + "label": "合约名称", + "type": "input" + }, + "accessPolicy": { + "label": "访问控制策略", + "type": "input", + "option": [ + { + "text": "无访问控制", + "value": "NAC" + }, + { + "text": "直接访问控制", + "value": "DAC" + }, + { + "text": "基于角色的访问控制", + "value": "RBAC" + } + ] + }, + "dbUserName": { + "label": "用户名", + "type": "input" + }, + "fieldList": { + "label": "字段名", + "type": "tag" + }, + "dbUrl": { + "label": "数据库链接", + "type": "input" + }, + "tableName": { + "label": "表名", + "type": "input" + } + }, + "apiName": "generateMySQLProject" + }, + { + "formDesc": { + "contractName": { + "label": "合约名称", + "type": "input" + }, + "accessPolicy": { + "label": "访问控制策略", + "type": "input", + "option": [ + { + "text": "无访问控制", + "value": "NAC" + }, + { + "text": "直接访问控制", + "value": "DAC" + }, + { + "text": "基于角色的访问控制", + "value": "RBAC" + } + ] + } + }, + "apiName": "generateEmptyProject" + } + ], + "action": "onTemplateList" + } + +空白合约模板 +^^^^^^^^^^^^ + +.. _参数-72: + +参数 +'''' + +============ ============================= +字段 值 +============ ============================= +action generateEmptyProject +contractName 字符串类型,合约名称 +isPrivate 布尔类型,是否为私有项目 +accessPolicy 若为“DAC”,则实现直接访问控制 +============ ============================= + +.. _请求示例-72: + +请求示例 +'''''''' + +.. code:: javascript + + var req = {}; + req.contractName = "Empty22"; + req.action = "generateEmptyProject"; + req.accessPolicy = "DAC"; + //wssocket为建立好的连接 + wssocket.send(JSON.stringify(req)); + +.. _返回结果-43: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onListProjects", + "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\"]", + "executeTime":0, + "isPrivate":false + } + +MySQL接入合约 +^^^^^^^^^^^^^ + +.. _参数-73: + +参数 +'''' + +============= ====================================================== +字段 值 +============= ====================================================== +action generateMySQLProject +contractName 字符串类型,合约名称 +isPrivate 布尔类型,是否为私有项目 +dbUrl 字符串类型,数据库的URI +dbUserName 字符串类型,数据库的用户名 +dbPWD 字符串类型,数据库密码 +accessPolicy 若为“DAC”,则实现直接访问控制,若为“NAC”则没有访问控制 +tableName 字符串类型,数据库的表名 +fieldList 字符串列表,数据库的字段列表 +defaultAccept 布尔值,表示申请时是否默认有权 +============= ====================================================== + +.. _请求示例-73: + +请求示例 +'''''''' + +.. code:: javascript + + var req = {}; + req.contractName = "MySQLFromTemplate"; + req.action = "generateMySQLProject"; + req.pubKey = global.sm2Key.publicKey; + req.isPrivate = true; + req.tableName = "data"; + req.dbUrl = "jdbc:mysql://xxx:xxx/xxx"; + req.dbUserName = "loushuai"; + req.dbPWD = "loushuai"; + req.fieldList = [{"name":"名字","code":"*"}]; + req.basicInfo={"type":"所属分类","name":"资源名称"}; + req.accessPolicy = "DAC"; + req.defaultAccept = true; + //global.wssocket为建立好的连接 + global.wssocket.send(JSON.stringify(req)); + +.. _返回结果-44: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true + } + +CSV接入合约 +^^^^^^^^^^^ + +.. _参数-74: + +参数 +'''' + +================= ====================================================== +字段 值 +================= ====================================================== +action generateCSVProject +contractName 字符串类型,合约名称 +base64EncodedData 字符串类型,通过base64编码后的CSV文件内容 +isPrivate 可选字段,布尔类型,是否为私有项目 +accessPolicy 若为“DAC”,则实现直接访问控制,若为“NAC”则没有访问控制 +defaultAccept 可选字段,布尔值,表示申请时是否默认有权 +================= ====================================================== + +.. _请求示例-74: + +请求示例 +'''''''' + +.. code:: javascript + + var req = {}; + req.contractName = "CSVFromTemplate"; + req.action = "generateCSVProject"; + req.pubKey = global.sm2Key.publicKey; + req.isPrivate = true; + req.tableName = "data"; + req.accessPolicy = "DAC"; + req.defaultAccept = true; + req.base64EncodedData = "bmFtZSwgc2NvcmUsCmphY2ssIDkwLApsdWN5LCA5MQo="; + //global.wssocket为建立好的连接 + global.wssocket.send(JSON.stringify(req)); + +.. _返回结果-45: + +返回结果 +'''''''' + +.. code:: json + + { + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true + } + +-------------- + +路由节点WebSocket接口 +--------------------- + +.. _用户管理类-2: + +用户管理类 +~~~~~~~~~~ + +.. _获取session-1: + +获取Session +^^^^^^^^^^^ + +登录前获取session以便进行签名。 + +.. _参数-75: + +参数 +'''' + +====== ============ +字段 值 +====== ============ +action getSessionID +====== ============ + +.. _请求示例-75: + +请求示例 +'''''''' + +:: + + var req = {}; + req.action = "getSessionID"; + wssocket.send(JSON.stringify(req)); + +.. _返回结果-46: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onSessionID", + "session": "9782323_session" + } + +.. _用户登录-1: + +用户登录 +^^^^^^^^ + +用户进行公私钥身份验证,需先调用“getSessionID”获取sessionID以便于签名。 + +.. _参数-76: + +参数 +'''' + +====== ===== +字段 值 +====== ===== +action login +====== ===== + +.. _请求示例-76: + +请求示例 +'''''''' + +:: + + var loginParam = {}; + loginParam.pubKey = global.sm2Key.publicKey; + loginParam.signature = sm2.doSignature(global.session, + global.sm2Key.privateKey); + loginParam.action = "login"; + wssocket.send(JSON.stringify(loginParam)); + +.. _返回结果示例-25: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "action": "onLogin", + "data": "CenterManager" + } + +用户获取当前角色(删除) +^^^^^^^^^^^^^^^^^^^^^^ + +用户根据登录时的公钥获取对应的角色,如果是第一次登录则此时的公钥默认称为准入管理员 + +.. _参数-77: + +参数 +'''' + +====== ======= +字段 值 +====== ======= +action getRole +====== ======= + +.. _请求示例-77: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "getRole"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果示例-26: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "action": "onGetRole", + "data": "CenterManager" + } + +.. _申请角色-1: + +申请角色 +^^^^^^^^ + +在准入管理员界面可以申请称为组网中某个节点的节点管理员 + +.. _参数-78: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action applyRole +role 申请的角色名称 +====== ============== + +.. _请求示例-78: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "applyRole"; + param.role=" + wssocket.send(JSON.stringify(param)); + +.. _返回结果示例-27: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "action": "onApplyRole", + "data": "failed" + } + +添加节点 +^^^^^^^^ + +.. _参数-79: + +参数 +'''' + +========== ================ +字段 值 +========== ================ +action addNode +nodePubKey 要添加的节点公钥 +========== ================ + +.. _请求示例-79: + +请求示例 +^^^^^^^^ + +:: + + var req = {}; + //某节点的publicKey可通过连接该节点,并通过"获取节点配置信息"接口获取 + req.nodePubKey = publicKey; + req.action = "addNode"; + wssocket.send(JSON.stringify(req)); + +.. _删除用户角色-1: + +删除用户角色 +^^^^^^^^^^^^ + +.. _参数-80: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action delete +pubKey 对应用户的公钥 +====== ============== + +.. _请求示例-80: + +请求示例 +'''''''' + +:: + + var deleteInfo = {}; + deleteInfo.pubKey = user.publicKey; + deleteInfo.action = "delete"; + wssocket.send(JSON.stringify(deleteInfo)); + +.. _返回结果示例-28: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "action": "onDelete", + "data": "success" + } + +.. _查看授权用户列表-1: + +查看授权用户列表 +^^^^^^^^^^^^^^^^ + +查看准入管理员当前组网中已经授权的节点管理员 + +.. _参数-81: + +参数 +'''' + +====== ============ +字段 值 +====== ============ +action listAllUsers +====== ============ + +.. _请求示例-81: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "onListAllUsers"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果示例-29: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "action": "onListAllUsers", + "kv": { + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": " NodeManager" + }, + "time": { + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": 1587398989914 + } + } + +.. _查看申请用户列表-1: + +查看申请用户列表 +^^^^^^^^^^^^^^^^ + +.. _参数-82: + +参数 +'''' + +====== ============= +字段 值 +====== ============= +action listApplyList +====== ============= + +.. _请求示例-82: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "onListApplyList"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-47: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onListApplyList", + "kv": { + "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7", + "value": " NodeManager" + }, + "time": { + "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7", + "value": 1587398989914 + } + } + +查看用户类型分布 +^^^^^^^^^^^^^^^^ + +.. _参数-83: + +参数 +'''' + +====== ============= +字段 值 +====== ============= +action queryUserStat +====== ============= + +.. _请求示例-83: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "onQueryUserStat"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果示例-30: + +返回结果示例 +'''''''''''' + +.. code:: json + + { + "action": "onQueryUserStat", + "userListCount": 3, + "applyListCount":0 + } + +节点管理类 +~~~~~~~~~~ + +查看节点列表 +^^^^^^^^^^^^ + +查看该用户有权限查看的节点列表(仅准入管理员及合约管理者可用) + +.. _参数-84: + +参数 +'''' + +====== ========= +字段 值 +====== ========= +action listNodes +====== ========= + +.. _请求示例-84: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "listNodes"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-48: + +返回结果 +'''''''' + +.. code:: json + + { + "offline": [{ + "key": "0431e31...40009b4f06d", + "value": "0431e311bd708...b4f06d" + }], + "action": "onListNodes", + "online": [{ + "contracts": [], + "pubKey": "0431e311...09b4f06d", + "nodeName": "NewNodeName", + "udpID": "528822126", + "cimanager": "" + }] + } + +查看可信执行集群列表 +^^^^^^^^^^^^^^^^^^^^ + +查看该用户有权限查看的节点列表(仅中心管理员及合约管理者可用) + +.. _参数-85: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action listTrustUnits +====== ============== + +.. _请求示例-85: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "listTrustUnits"; + wssocket.send(JSON.stringify(param)); + +.. _返回结果-49: + +返回结果 +'''''''' + +.. code:: json + + { + "data": [{ + "key": "0470b2f27f4f6…1cb855f1ecec11", + "value": "[...]" + }], + "action": "onListTrustUnits" + } + +建立可信执行集群 +^^^^^^^^^^^^^^^^ + +.. _参数-86: + +参数 +'''' + +====== ====================== +字段 值 +====== ====================== +action createTrustUnit +data 节点公钥组成的Json数组 +Msg 集群名称 +====== ====================== + +.. _请求示例-86: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "createTrustUnit"; + param.data = "[\"382r0934309t...\",\"345343rr3f34...\"]"; + param.msg = "newUnit1"; + global.wssocket.send(JSON.stringify(param)); + +.. _返回结果-50: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onCreateTrustUnit", + "status": "Success" + } + +删除可信执行集群 +^^^^^^^^^^^^^^^^ + +.. _参数-87: + +参数 +'''' + +====== =============== +字段 值 +====== =============== +action deleteTrustUnit +data 可信执行集群ID +====== =============== + +.. _请求示例-87: + +请求示例 +'''''''' + +:: + + var param = {}; + param.action = "deleteTrustUnit"; + param.data = "0475d34rf3434..._1583410158761"; + global.wssocket.send(JSON.stringify(param)); + +.. _返回结果-51: + +返回结果 +'''''''' + +.. code:: json + + { + "action": "onDeleteTrustUnit", + "status": "Success" + } + +.. _日志查看类-2: + +日志查看类 +~~~~~~~~~~ + +查看组网管理操作的统计 +^^^^^^^^^^^^^^^^^^^^^^ + +.. _参数-88: + +参数 +'''' + +====== ============== +字段 值 +====== ============== +action queryActionLog +date 当前时间 +====== ============== + +.. _请求示例-88: + +请求示例 +'''''''' + +:: + + request.action = "onQueryActionLog"; + request.date = new Date().getTime() - 24 * 3600 * 1000 * n; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-52: + +返回结果 +'''''''' + +.. code:: json + + { "action":"onQueryActionLog", + "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]" + } + +查看本地近n日合约日志 +^^^^^^^^^^^^^^^^^^^^^ + +.. _参数-89: + +参数 +'''' + +====== ==================== +字段 值 +====== ==================== +action listLocalContractLog +date 当前时间 +====== ==================== + +.. _请求示例-89: + +请求示例 +'''''''' + +:: + + request.action = "listLocalContractLog"; + request.date = new Date().getTime() - 24 * 3600 * 1000 * n; + wssocket.send(JSON.stringify(request)); + +.. _返回结果-53: + +返回结果 +'''''''' + +.. code:: json + + { + "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7b...\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]" + } + +-------------- + +Bash接口 +-------- + +已废弃。可使用BDWareConfigTool代替。 通过命令行发送Socket指令, +执行调用\ ``ContractController``\ 类中方法, 完成以下功能. +(需要在本机的``1615``\ 端口运行\ ``ContractManager``\ 实例) + +.. figure:: ./_static/imgs/bash-api.png + :alt: Bash接口功能示意图 + + Bash接口功能示意图 + +指令 +~~~~ + +.. code:: bash + + java -jar yjs.jar function_name arguments + +``function_name``\ 为调用的方法名; + +``arguments``\ 为方法参数. + +.. _启动合约-2: + +启动合约 +~~~~~~~~ + +.. _参数-90: + +参数 +^^^^ + +``function_name``\ 为\ ``startContract``; + +``arguments``\ 为启动合约需要的参数, 包括合约类型\ ``type``, +合约ID\ ``id``, 合约脚本\ ``script``. + +指令示例 +^^^^^^^^ + +.. code:: bash + + java -jar yjs.jar startContract "{\"type\":\"Algorigthm\",\"id\":\"656565\",\"script\":\"contract c{function main(arg){return arg/1.0+1;}}\"}" + +.. _调用合约-2: + +调用合约 +~~~~~~~~ + +.. _参数-91: + +参数 +^^^^ + +``function_name``\ 为\ ``executeContract``; + +``arguments``\ 为调用合约需要的参数, 包括调用参数\ ``arg``, +合约ID\ ``contractID``. + +.. _指令示例-1: + +指令示例 +^^^^^^^^ + +.. code:: bash + + java -jar yjs.jar executeContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}" + +.. _停止合约-1: + +停止合约 +~~~~~~~~ + +.. _参数-92: + +参数 +^^^^ + +``function_name``\ 为\ ``stopContract``; + +``arguments``\ 为调用合约需要的参数, 即合约ID\ ``contractID``. + +.. _指令示例-2: + +指令示例 +^^^^^^^^ + +.. code:: bash + + java -jar yjs.jar stopContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}" + +停止全部合约 +~~~~~~~~~~~~ + +.. _参数-93: + +参数 +^^^^ + +``function_name``\ 为\ ``stopAllContracts``. + +.. _指令示例-3: + +指令示例 +^^^^^^^^ + +.. code:: bash + + java -jar yjs.jar stopAllContracts + +查询全部合约 +~~~~~~~~~~~~ + +.. _参数-94: + +参数 +^^^^ + +``function_name``\ 为\ ``listContracts``. + +.. _指令示例-4: + +指令示例 +^^^^^^^^ + +.. code:: bash + + java -jar yjs.jar listContracts diff --git a/doc/_sources/IDEUsage.rst.txt b/doc/_sources/IDEUsage.rst.txt new file mode 100644 index 0000000..2fa95fd --- /dev/null +++ b/doc/_sources/IDEUsage.rst.txt @@ -0,0 +1,672 @@ +BDContract管理界面 +================== + +-------------- + +合约节点管理界面 +---------------- + +该界面的使用地址为:\ `NodePortal.html `__ + +用户管理菜单 +~~~~~~~~~~~~ + +用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。 + +概览 +^^^^ + +|nodeUserManager| +节点用户管理页面一共有四个模块:用户情况、用户活跃统计、授权用户管理、未授权用户管理。 + +用户类型分布 +^^^^^^^^^^^^ + +主要统计当前节点管理员所拥有的四种角色的数量:合约提供者、合约管理员、合约使用者 +|userList| + +用户活跃统计 +^^^^^^^^^^^^ + +|userActive| 统计30天之内\ **登录**\ 、\ **授权**\ 、\ **申请**\ 的次数 + +当前用户信息 +^^^^^^^^^^^^ + +|nodeInfo| \* +在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录节点管理员界面,可以将自己的公私钥复制到这个文本框中。 +\* +将自己的公私钥复制完成之后要点击\ **导入公钥**\ ,将公钥加入到节点管理员本地 +\* +然后在\ **本地公钥**\ 中可以看见公钥的前五位,选择自己的公钥,将在\ **我的权限**\ 中展示出当前选择的公钥的角色,如果是还没有在中心管理员认证的节点则默认为\ **Anonymous** +\* +如果不是节点管理员,想要加入某个中心管理员的网络,那么要在中心管理员所在的用户管理中用自己的公私钥导入后进行认证。 +\* +如果想要行使更多关于合约的操作,则需要认证不同的角色:合约管理员、合约使用者、合约提供者,然后进行\ **角色认证** + +授权与非授权用户列表 +^^^^^^^^^^^^^^^^^^^^ + +|roleAuth| +在节点管理员认证角色之后,节点管理员登录会在\ **未授权角色管理**\ 表格中看见带有公钥的申请信息,如果同意,则点击\ **授权**\ ,如果不同意点击\ **忽略**\ 就可以。 +授权之后将在\ **授权角色管理**\ 表格中看见授权后的节点列表。如果节点管理员想要移除某个节点的角色,则在授权角色管理列表中\ **删除**\ 即可。 + +合约代码管理菜单 +~~~~~~~~~~~~~~~~ + +.. figure:: ./_static/imgs/codeManageMenu.png + :alt: codeManageMenu + + codeManageMenu + +合约文件 +^^^^^^^^ + +.. figure:: ./_static/imgs/codeManage1.png + :alt: codeManage1 + + codeManage1 + +在合约代码管理菜单中,用户可以看到公共合约以及个人私有合约。 +|codeManage1-1| + +对于公共合约,节点管理员可以对其中文件进行删除和上传操作,可以对合约项目进行下载和删除操作。 +|codeManage1-2| + +对于私有合约,合约提供者可以对其中文件进行删除和上传操作,可以对合约项目进行下载、删除和传至公共合约目录操作。 + +以下是对合约文件进行操作的示例。 + +上传文件 +^^^^^^^^ + +.. figure:: ./_static/imgs/codeManage6.png + :alt: codeManage6 + + codeManage6 + +删除 +^^^^ + +.. figure:: ./_static/imgs/codeManage5.png + :alt: codeManage5 + + codeManage5 + +传至公共 +^^^^^^^^ + +.. figure:: ./_static/imgs/codeManage7.png + :alt: codeManage7 + + codeManage7 + +下拉框 +^^^^^^ + +.. figure:: ./_static/imgs/codeManage2.png + :alt: codeManage2 + + codeManage2 + +四个下拉框中,可以分别对合约状态保存模式、已启动合约实例、节点所在集群以及结果校验方式进行选择。 + +按钮操作 +^^^^^^^^ + +.. figure:: ./_static/imgs/codeManage3.png + :alt: codeManage3 + + codeManage3 + +启动 +^^^^ + +在文件列表中选择合约文件之后,在合约运行模式中选择“单节点执行”,点击启动按钮,会启动指定文件,并在结果显示框中显示返回结果。 + +启动P2P集群合约 +^^^^^^^^^^^^^^^ + +在文件列表中选择合约文件之后,在合约运行模式中选择该可信合约运行的合约集群,点击启动按钮,会在该集群的所有节点上启动指定文件,并在结果显示框中显示返回结果。 + +启动全部 +^^^^^^^^ + +在合约运行模式中选择“单节点执行”,点击启动全部按钮,会启动合约文件列表中所有合约。 + +停止P2P集群合约 +^^^^^^^^^^^^^^^ + +在已启动合约实例的下拉框中选择一个合约实例,在合约运行模式中选择该可信合约运行的合约集群,点击停止按钮,会在该集群的所有节点上终止这个合约进程。 + +停止 +^^^^ + +在已启动合约实例的下拉框中选择一个合约实例,点击停止按钮,会终止这个合约进程。 + +停止全部 +^^^^^^^^ + +点击停止全部按钮,会停止该节点上运行的所有合约实例。 + +静态分析 +^^^^^^^^ + +在合约文件列表中选择合约文件,并在合约实例下拉框中选择合约实例,点击静态分析按钮,会对该合约进行静态分析,并在结果显示框中显示返回结果。 + +分发合约 +^^^^^^^^ + +在合约文件列表中选择合约项目,并在合约运行模式中选择一个集群,点击分发合约按钮,会将该合约项目打包为ypk分发给这个集群中的所有节点。 + +返回结果 +^^^^^^^^ + +.. figure:: ./_static/imgs/codeManage4.png + :alt: codeManage4 + + codeManage4 + +返回结果显示中显示一些操作的返回结果。 + +合约权限配置 +^^^^^^^^^^^^ + +在启动合约之后,如果当前用户的角色可以查看已经启动合约进程,那么在选定查看合约进程时将会在右下方展示当前合约的IO权限。 +|permissionShow| + +如果选中的合约没有IO权限,则在当前权限的展示框中提示\ **当前合约没有IO权限** +|nullPermission| + +当前用户是合约管理员时可以对已有的合约IO权限进行修改。系统会提示修改后合约将有可能不会正常运行,如果还是确定要取消,那么点击\ **确定** +即可,反之点击\ **关闭** |updatePermission| + +点击关闭或者打开之后,下一次查看同一个合约代码的进程将会默认显示最近一次修改之后的IO权限。 +|closePermission| + +合约实例管理菜单 +~~~~~~~~~~~~~~~~ + +.. figure:: ./_static/imgs/nodeInstancesPage.png + :alt: nodeInstancesPage + + nodeInstancesPage + +合约实例管理菜单显示了该节点当前的所有合约实例, +用户可查看合约实例的状态, 并对合约实例进行执行或状态迁移的操作. + +合约实例列表 +^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/nodeInstancesList.png + :alt: nodeInstancesList + + nodeInstancesList + +该列表显示了当前节点的所有合约实例信息, 包括合约ID, 合约名称, +合约类型合约状态, 合约进程端口, 合约调用次数, 合约流量, 及合约占用内存, +集群合约的结果校验模式. + +合约实例执行 +^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/chooseInstance.png + :alt: chooseInstance + + chooseInstance + +用户可在合约实例的选择下拉框中选择合约实例, 对该合约实例进行操作. + +.. figure:: ./_static/imgs/intanceExecute.png + :alt: intanceExecute + + intanceExecute + +选择合约实例后, 用户可在“方法”的下拉框中选择该合约的方法名, +在“参数”输入框中输入方法的参数, 点击“执行”. + +用户还可点击“动态分析执行”进行带有动态分析结果的执行. + +若该合约为单点合约, 则合约在单点执行; 若该合约为集群合约, +则该合约在该集群的所有节点上执行. + +合约实例执行结果 +^^^^^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/executeResult.png + :alt: executeResult + + executeResult + +合约实例的执行完成后的结果显示在“执行结果”区域中, 包括该次执行的ID, +执行成功/失败, 执行时间, 及执行结果. + +.. figure:: ./_static/imgs/analysisExecuteResult.png + :alt: analysisExecuteResult + + analysisExecuteResult + +若该合约的执行方式为“动态分析执行”, 则结果框内除执行结果, +还会显示该次执行的动态分析结果. + +合约状态迁移 +^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/memoryDump.png + :alt: memoryDump + + memoryDump + +对于支持用户手动迁移的合约实例, +用户可点击“本地状态保存”对合约实例的状态进行保存, +或从合约的TimeTravel列表中选择已保存的合约实例, +将合约状态迁移到对应时刻. + +日志管理菜单 +~~~~~~~~~~~~ + +.. figure:: ./_static/imgs/logMenu.png + :alt: logMenu + + logMenu + +该菜单是对该节点本地节点日志以及合约日志的统计结果展示。 + +其中,节点管理员可以查看节点日志的相关数据;合约管理者及合约使用者可以查看该节点本地合约日志的相关数据。 + +日志统计图 +^^^^^^^^^^ + +.. figure:: ./_static/imgs/log1.png + :alt: log1 + + log1 + +各类平台操作百分比 +^^^^^^^^^^^^^^^^^^ + +该图默认显示近2日各类平台操作占比的饼图,其中平台操作分为登陆类、用户类、日志类、合约类、维护类以及其他类这六类。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比会同步更新。 + +各类合约操作百分比 +^^^^^^^^^^^^^^^^^^ + +合约操作分为启动、终止、静态分析和执行这四类,该图为近2日对各类合约操作占比的饼图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比会同步更新。 + +每日平台使用统计 +^^^^^^^^^^^^^^^^ + +该图为近2日平台操作次数统计的折线图。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日平台使用统计折线图会同步更新。 + +每日合约使用统计 +^^^^^^^^^^^^^^^^ + +该图为近2日对该节点上合约的操作次数统计的折线图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日合约使用统计折线图会同步更新。 + +日志详情 +^^^^^^^^ + +节点日志详情 +^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/log2.png + :alt: log2 + + log2 + +节点日志详情表是对节点日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比和每日平台使用统计会同步更新。 + +合约日志详情 +^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/log3.png + :alt: log3 + + log3 + +合约日志详情表是对合约日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比和每日合约使用统计会同步更新。 + +节点管理菜单 +~~~~~~~~~~~~ + +.. figure:: ./_static/imgs/nodeConfig.png + :alt: nodeConfig + + nodeConfig + +节点管理菜单显示了该节点的配置信息及所属可信执行集群信息. + +节点配置 +^^^^^^^^ + +.. figure:: ./_static/imgs/nodeConfigChange.png + :alt: nodeConfigChange + + nodeConfigChange + +节点管理员可查看该节点的配置信息, 包括节点名称, 节点YJS路径, +节点的网络中心节点, 节点管理员还可对以上配置进行修改. + +若节点管理员修改了节点的网络中心, 该节点后重新想改节点连接, +整个页面刷新重载. + +节点可信执行集群列表 +^^^^^^^^^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/nodeUnits.png + :alt: nodeUnits + + nodeUnits + +节点管理员可查看节点所属的可信执行集群信息, 包括集群创建者, 集群ID, +集群中节点数目, 集群中节点的信息. + +-------------- + +节点Licence配置 +^^^^^^^^^^^^^^^ + +.. figure:: ./_static/imgs/nodeLicence.png + :alt: nodeLicence + + nodeLicence + +用户可以查看该节点的Licence及过期时间, 还可申请Licence, 上传Licence, +保存节点UUID. + +智能合约在线编辑器 +------------------ + +用户与账号 +~~~~~~~~~~ + +创建账号 +^^^^^^^^ + +申请授权 +^^^^^^^^ + +创建项目 +~~~~~~~~ + +新建文件 +^^^^^^^^ + +.. _上传文件-1: + +上传文件 +^^^^^^^^ + +启动合约 +~~~~~~~~ + +.. figure:: ./_static/imgs/contractMode.png + :alt: contractMode + + contractMode + +####正常模式 点击左侧启动按钮,以正常模式启动合约。 + +####debug模式 +点击右侧debug按钮,以debug模式启动合约。目前约定debug模式合约通过executeContract调用正常模式合约时,返回正常模式合约文档中的返回结果示例。 + +调用合约 +~~~~~~~~ + +###生成文档 |genReadme| + +启动合约后点击“生成文档”按钮,可以通过各export函数的@Description / +@Param / @Result 对合约进行调用及结果返回,从而生成合约的说明文档。 + +-------------- + +路由准入管理界面 +---------------- + +权限申请与授权 +~~~~~~~~~~~~~~ + +仪表盘 +~~~~~~ + +仪表盘为提供对准入节点中用户数量,合约数量,节点数量的概览。 + +整体视图 +~~~~~~~~ + +|dashboard| +一共分为四个模块,一个模块是用户、合约、节点数量的概览,然后分别是这三个数量的详细分类的数据统计情况。 + +节点数目 +~~~~~~~~ + +|node| 当前在线和离线节点统计 + +.. _用户类型分布-1: + +用户类型分布 +~~~~~~~~~~~~ + +|userAll| +当前准入节点所在组网中的节点管理员、准入管理员的数量和申请中节点的数量 + +合约调用情况 +~~~~~~~~~~~~ + +|contract| +当前准入节点所在组网中所有合约中事件、多点执行、ws调用、Http调用的折线统计图。 + +用户管理 +~~~~~~~~ + +用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。 + +.. _概览-1: + +概览 +~~~~ + +|centerManager| 用户管理页面一共有四个模块。 + +.. _用户类型分布-2: + +用户类型分布 +~~~~~~~~~~~~ + +主要统计当前中心管理员所管理的网络中有多少节点管理员,多少个中心管理以及申请节点管理员的数量 +|userList| + +30天内的申请情况统计 +~~~~~~~~~~~~~~~~~~~~ + +|userApplyGraph| +统计30天之内申请节点管理员的数量和授权成为节点管理员的数量 + +.. _当前用户信息-1: + +当前用户信息 +~~~~~~~~~~~~ + +|authNodeManager| \* +在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录中心管理员界面,可以将自己的公私钥复制到这个文本框中。 +\* +将自己的公私钥复制完成之后要点击\ **导入公钥**\ ,将公钥加入到中心管理员本地 +\* +然后在\ **本地公钥**\ 中可以看见公钥的前五位,选择自己的公钥,将在\ **我的权限**\ 中展示出当前选择的公钥的角色,如果是中心管理员则拥有中心管理员的一切权限。 +\* +如果不是中心管理员或者节点管理员,想要加入当前中心管理员的网络,那么可以在下面的选择框中选中节点管理员,进行\ **角色认证**\ 。 + +.. _授权与非授权用户列表-1: + +授权与非授权用户列表 +~~~~~~~~~~~~~~~~~~~~ + +在中心管理员当前用户信息申请之后,中心管理员登录会在\ **未授权用户管理**\ 表格中看见带有公钥的申请信息,如果同意,则点击\ **授权**\ ,如果不同意点击\ **忽略**\ 就可以,此时这个申请就无效。 +|authMan| +授权之后将在\ **授权用户管理**\ 表格中看见授权后的节点列表。如果中心管理员想要移除某个节点管理员的某项角色,则在授权用户管理列表中选择相应的角色,然后点击\ **删除**\ 即可删除选中的角色。 +|authMana| + +节点管理 +~~~~~~~~ + +.. figure:: ./_static/imgs/centerNodePage.png + :alt: centerNodePage + + centerNodePage + +节点管理为Manager对连接到自己的Cluster节点进行管理的页面, +仅Manager管理员及合约管理者可见. +Manager管理员及合约管理者可在本页面查看节点信息, 并管理可信执行集群. + +.. _概览-2: + +概览 +~~~~ + +.. figure:: ./_static/imgs/centerNodePreview.png + :alt: centerNodePreview + + centerNodePreview + +概览中显示了该Manager节点所管理的所有节点的统计信息, 包括总节点数量, +总合约数量, 总订阅事件数量, 及可信执行集群数量, +右侧的饼图则为节点的分别处于Online/Offline的数量统计. + +节点列表 +~~~~~~~~ + +.. figure:: ./_static/imgs/centerNodeList.png + :alt: centerNodeList + + centerNodeList + +节点列表显示了用户有权限查看的节点信息(Manager管理员可查看全部节点, +合约管理者可查看自己负责管理的Online节点). 包括节点的名称, 状态, +合约数目, 订阅事件数目, 用于节点间P2P通信的PeerID, +用于节点间UDP通信的UDPID, 及节点公钥. + +可信执行集群列表 +~~~~~~~~~~~~~~~~ + +.. figure:: ./_static/imgs/centerNodeUnits.png + :alt: centerNodeUnits + + centerNodeUnits + +可信执行集群列表显示了用户有权限查看的可信执行集群信息(Manager管理员可查看全部集群, +合约管理者可查看自己创建的集群). 包括集群的创建者, 集群ID, +集群中节点数目, 以及集群中节点的信息. + +用户可点击列表表项的“删除”按钮, 将该集群删除. + +创建可信执行集群 +~~~~~~~~~~~~~~~~ + +.. figure:: ./_static/imgs/centerNodeUnitCreate.png + :alt: centerNodeUnitCreate + + centerNodeUnitCreate + +用户可以通过多选节点, 创建新的可信执行集群. +用户可以选择的节点为自己有权限查看的节点, +即Manager管理员从全部节点中选择, +合约管理者可从自己负责管理的Online节点中选择). 选择后点击提交, +即可看到创建成功的提示信息, 该集群将随即显示在可信执行集群列表中. +集群名称由创建者选取, 不能含有双引号, +该名称为合约管理者选择集群时的可见标识. + +日志管理 +~~~~~~~~ + +日志管理主要展示准入节点的各项日志信息,一共分为六个模块。 ### 概览 +|log| + +管理操作分类统计(2日) +~~~~~~~~~~~~~~~~~~~~~~~ + +|operator| +两日内所有管理类操作的统计饼图,管理类操作主要分为登录类、日志类、维护类、用户类。 + +管理操作每日统计(2日) +~~~~~~~~~~~~~~~~~~~~~~~ + +|everyLog| 两日内管理类所有的操作每日操作统计 + +合约操作分类统计(2日) +~~~~~~~~~~~~~~~~~~~~~~~ + +|contractLog| +两日内合约操作分类统计饼图,合约操作主要分为连接类和状态更新类。 + +合约操作每日统计(2日) +~~~~~~~~~~~~~~~~~~~~~~~ + +|contracteveryLog| 两日内合约操作数量折线统计图。 + +管理操作日志列表 +~~~~~~~~~~~~~~~~ + +|opList| +管理操作日志的详细信息列表。包括日志时间,管理操作名称,操作对应的节点公钥。默认展示范围是两天,可以自定义获取日志的天数。 + +合约操作日志列表 +~~~~~~~~~~~~~~~~ + +|contractList| +合约操作日志详细信息列表。包括日志产生时间,合约操作名称,合约操作节点公钥。默认展示范围是两天,可以自定义获取日志的天数。 + +设置 +~~~~ + +设置页面是节点证书的状态展示以及配置节点证书 + +.. _概览-3: + +概览 +~~~~ + +.. figure:: ./_static/imgs/set.jpg + :alt: set + + set + +证书状态 +~~~~~~~~ + +|licence| 证书状态主要包括许可到期时间和许可节点数量。 + +配置证书 +~~~~~~~~ + +|plicence| 配置证书模块可以下载节点ID文件或者输入证书信息进行提交。 + +.. |nodeUserManager| image:: ./_static/imgs/nodeUserManager.jpg +.. |userList| image:: ./_static/imgs/userList.jpg +.. |userActive| image:: ./_static/imgs/userActive.jpg +.. |nodeInfo| image:: ./_static/imgs/nodeInfo.jpg +.. |roleAuth| image:: ./_static/imgs/roleAuth.jpg +.. |codeManage1-1| image:: ./_static/imgs/codeManage1-1.png +.. |codeManage1-2| image:: ./_static/imgs/codeManage1-2.png +.. |permissionShow| image:: ./_static/imgs/permissionShow.png +.. |nullPermission| image:: ./_static/imgs/nullPermission.png +.. |updatePermission| image:: ./_static/imgs/updatePermission.png +.. |closePermission| image:: ./_static/imgs/closePermission.png +.. |genReadme| image:: ./_static/imgs/genReadme.png +.. |dashboard| image:: ./_static/imgs/dashboard.jpg +.. |node| image:: ./_static/imgs/node.jpg +.. |userAll| image:: ./_static/imgs/userAll.jpg +.. |contract| image:: ./_static/imgs/contract.jpg +.. |centerManager| image:: ./_static/imgs/centerManager.jpg +.. |userApplyGraph| image:: ./_static/imgs/userApplyGraph.jpg +.. |authNodeManager| image:: ./_static/imgs/authNodeManager.jpg +.. |authMan| image:: ./_static/imgs/authMan.jpg +.. |authMana| image:: ./_static/imgs/authMana.jpg +.. |log| image:: ./_static/imgs/log.jpg +.. |operator| image:: ./_static/imgs/operator.jpg +.. |everyLog| image:: ./_static/imgs/everyLog.jpg +.. |contractLog| image:: ./_static/imgs/contractLog.jpg +.. |contracteveryLog| image:: ./_static/imgs/contracteveryLog.jpg +.. |opList| image:: ./_static/imgs/opList.jpg +.. |contractList| image:: ./_static/imgs/contractList.jpg +.. |licence| image:: ./_static/imgs/licence.jpg +.. |plicence| image:: ./_static/imgs/plicence.jpg + diff --git a/doc/_sources/InstallTips.rst.txt b/doc/_sources/InstallTips.rst.txt new file mode 100644 index 0000000..3733755 --- /dev/null +++ b/doc/_sources/InstallTips.rst.txt @@ -0,0 +1,223 @@ +BDContract安装说明 +================== + +-------------- + +依赖环境的安装 +-------------- + +1.安装Java1.8环境。 + +例如,在Ubuntu下使用apt-get进行安装: + +.. code:: bash + + apt-get install openjdk-8-jre + +在Centos环境下,使用yum进行安装: + +.. code:: bash + + yum install java-1.8.0-openjdk + +如果是离线环境,可先下载openjdk的安装包后进行离线安装。 + +Ubuntu下 + +.. code:: bash + + dpkg -i jdk-8uxxxxx.deb + +在Centos环境下,使用yum进行离线安装: + +.. code:: bash + + yum localinstall jdk-8u271-linux-xxx.rpm + +2.安装wget与unzip。 例如,在Ubuntu下使用apt-get进行安装: + +.. code:: bash + + apt-get install unzip + apt-get install wget + +-------------- + +网络拓扑说明 +------------ + +部署数瑞智能合约引擎最小仅需一个节点,此时可用作调试、测试,不能通过多节点模式来实现可信的计算。 +单节点部署时,可通过配置账本实现“防抵赖”的计算,但不能实现“难篡改”的计算。 + +多节点部署时可参考下图,包含三种逻辑节点,同一虚拟机可安装一至三种节点。 + +1)账本节点。即数瑞图式账本。 + +2)合约节点。运行代码逻辑,并通过内存缓存实现高响应的模块。与其他合约节点组成可信计算网络。 + +3)路由节点。各个合约节点的路由信息。一般单个路由节点可支持最高1000合约节点。可视情况部署多个路由节点,并在路由节点之间配置实现更大规模的节点组网。 + +一般地,同一虚拟机下,会部署\ **合约节点与账本节点**\ 。 + +.. figure:: _static/imgs/deploytopology.png + :alt: deploytopology + + deploytopology + +-------------- + +智能合约节点安装 +---------------- + +打开\ `安装包下载链接 `__ +其中,下载\ ``bdserver-lite.zip``\ 或\ ``bdserver.zip``\ ,其中,\ ``bdserver.zip``\ 包含更多示例和文档。 +下载之后解压并启动。 + +.. code:: bash + + unzip -d ./bdserver bdserver-lite.zip + cd bdserver + chmod +x *.sh + sh cmstart.sh + +-------------- + +路由准入节点安装 +---------------- + +打开\ `安装包下载链接 `__ +其中,下载\ ``bdserver-cluster.zip``\ 。 下载之后解压并启动。 + +.. code:: bash + + unzip -d ./bdcluster bdserver-cluster.zip + cd bdcluster + chmod +x *.sh + sh ncstart.sh + +-------------- + +文件说明 +-------- + +智能合约节点 +~~~~~~~~~~~~ + +.. figure:: _static/imgs/dirstructure.png + :alt: bdserver目录 + + bdserver目录 + +该目录下的文件说明: + +1.cmstart.sh +该脚本用于启动合约引擎。合约引擎默认监听8080端口,可通过修改cmstart.sh来修改合约引擎的监听端口。 + +2.BDWareProjectDir 该目录存放了本节点的所有合约项目。 + +3.WebContent 该目录存放了本节点的前端代码。 + +4.cp, 该目录存放了yjs.jar,为启动合约实例所需的jar。 + +5.bdserver.jar 对外提供http/websocket的服务器逻辑。 + +6.updateContract.sh 用于升级的脚本。 + +路由准入节点 +~~~~~~~~~~~~ + +安装脚本会自动下载安装并解压为bdcluster目录。 该目录下的文件说明: + +1.ncstart.sh +该脚本用于启动节点准入中心。默认监听1718端口。可通过修改ncstart.sh来修改监听的端口。 + +2.WebContent 该目录存放了准入中心的前端代码。 + +3.bdcluster.jar 准入中心的后端。 + +-------------- + +升级流程 +-------- + +合约节点 +~~~~~~~~ + +在命令行中输入: + +.. code:: bash + + sh updateContract.sh + +亦可通过\ `public.internetapi.cn `__\ ,下载最新文件,单独升级yjs.zip/bdserver-jar.zip/AgentWebContent来升级。 + +.. _路由准入节点-1: + +路由准入节点 +~~~~~~~~~~~~ + +.. code:: bash + + sh updateCluster.sh + +亦可通过\ `public.internetapi.cn `__\ ,下载最新文件,单独升级bdserver-cluster.zip/ClusterWebContent.zip来升级。 + +-------------- + +使用说明 +-------- + +通过参考界面使用 +~~~~~~~~~~~~~~~~ + +当保留了WebContent目录的情况下,可使用浏览器进行配置。 +更多请使用见左侧文档\ `BDContract参考界面使用说明 <./IDEUsage.html>`__\ 。 + +BDWare OnlineIDE +^^^^^^^^^^^^^^^^ + +打开\ `BDWare OnlineIDE <../OnlineIDE.html>`__\ 。 + +BDWare NodePortal +^^^^^^^^^^^^^^^^^ + +打开\ `BDWare NodePortal <../NodePortal.html>`__\ 。 + +如需组网,使用跨节点功能,则需安装路由准入中心。并按以下步骤进行配置。涉及两组公私钥。 +第一组公私钥为合约节点的、有NodeManager权限的公私钥。 +第二组公私钥为路由准入节点的、有CenterManager权限的公私钥。 + +1.打开NodePortal.html,复制该节点的NodeManager公私钥。 + +2.打开CenterPortal.html,点击右上角,将上述的NodeManager公私钥导入;并选择“NodeManager”进行身份认证。 + +3.在CenterPortal.html中切换CenterManager的公私钥,点左侧的“用户管理”,通过NodeManager的认证请求。 + +4.使用NodeManager权限的公私钥打开NodePortal.html,点击:“节点管理”菜单,并配置加入网络。 +其中,加入网络的格式为:ws://centerportal的ip:端口+1。 |配置示例| + +通过SDK使用 +~~~~~~~~~~~ + +基础知识 +^^^^^^^^ + +`Websocket `__ + +`Sm2加密的使用 `__ + +SDK下载 +^^^^^^^ + +1. Java版本的客户端下载:\ `BDWareJavaClient <_static/BDWareJavaClient.zip>`__\ 。具体使用说明请下载后解压,查看README.md,并参考\ `ContractAPI <./ContractAPI.html>`__\ 。 + +2.Javascript版本的客户端下载:\ `BDWareWebClient <_static/BDWareWebClient.zip>`__\ 。具体使用说明请下载后解压,查看README.md,并参考\ `ContractAPI <./ContractAPI.html>`__\ 。 + +3.配置工具\ `BDWareConfigTool <_static/BDWareConfigTool.zip>`__\ 。具体说明请下载后解压,使用以下命令查看帮助: + +.. code:: bash + + java -jar java-client.jar -h + +.. |配置示例| image:: _static/imgs/config.png + diff --git a/doc/_sources/Introduction.rst.txt b/doc/_sources/Introduction.rst.txt new file mode 100644 index 0000000..7f63c3f --- /dev/null +++ b/doc/_sources/Introduction.rst.txt @@ -0,0 +1,242 @@ +BDContract介绍 +============== + +-------------- + +什么是BDContract? +----------------- + +北大数瑞是面向大数据场景的数据资源、IoT资源、云资源的管理、调度平台。BDContract是一个可信计算框架,计算逻辑以智能合约的方式表达。通过”随机“和”冗余计算“的方式实现智能合约的可信执行。BDContract在保证智能合约的可用性、可靠性的同时,着重提升执行效率和安全性。 + +-------------- + +特点 +---- + +0. 支持多种执行模式,权衡可用性、可靠性、正确性和效率。 +1. 接入各种数据源。 +2. 支持合约的细粒度监测。 +3. 支持合约的状态。 +4. 访问控制。 +5. 支撑跨语言调用。 + +-------------- + +更新日志 +-------- + +- **v1.4.3** 2021年6月9日 + + - 修复SSL Renegotiate Bug + - 实现内存不足时自动Hangup-Resume + - 实现contract meta的硬盘持久化 + +- **v1.4.1** 2021年5月26日 + + - 实现了事件机制中的事件语义,支持“至少一次”、“至多一次”和“只有一次” + - 优化了合约模板 + - 增加模板配置文件 + - 优化了MockTemplate注解 + +- **v1.4.0** 2021年5月9日 + + - 优化了ACTemplate + - 完善了DoRepo的配置联动 + +- **v1.3.9** 2021年4月22日 + + - 修复了doipConfig在updateConfig中不支持的bug + - test-tool支持了sudo + - 优化了contract-template中的ACTemplate模板 + +- **v1.3.6** 2021年4月21日 + + - 修复了docker中无法获取cpuid的问题 + +- **v1.3.6** 2021年4月16日 + + - 修复了部分bug + - 修复了GRPCPool线程数量不足导致排队的bug + - 修复了requestID分配在压力测试下可能重复的bug + +- **v1.3.5** 2021年3月31日 + + - 修复了部分bug + - http的合约调用部分增加了简单拥塞控制策略 + - 稳定性提升 + +- **v1.3.0** 2021年2月1日 + + - 优化心跳机制 + - 修复部分Bug + - 更新SM2/SM3库 + - 更新前端签名计算方式 + +- **v1.2.0** 2020年12月11日 + + - 优化了多节点执行模式 + - 优化了合约master路由的逻辑 + - 修复了部分bug + - 修复文件系统相关的漏洞 + +- **v1.1.0** 2020年9月 + + - 支持https,并更新了该部分文档 + +- **v1.0.9** 2020年8月27日 + + - 完善IO相关工具类的文档 + - 优化合约模板:DAC持久化 + +- **v1.0.7** 2020年8月13日 + + - 优化合约日志、账本接口 + - 优化相关接口的文档 + - 提供合约模板的websocket接口 + - 自动编译bug修复 + +- **v1.0.5** 2020年7月25日 + + - 弱化NC的中心化作用,集群点对点连接。 + - 优化bdwareclient + - TODO MemoryDurable + +- **v1.0.2** 2020年7月22日 + + - 修复CentOS7下Too Many Opened Files的Bug + - 修复权限Bug + - 增加权限说明 + - 修复MySQLUtil的bug + - 升级BDLedger版本 + +- **v1.0.1** 2020年7月5日 + + - 更新了NodePortal/CenterPortal的UI。 + - 修改了编译流程,在NodePortal中可查看编译结果,在OnlineIDE中可手动/启动时编译 + - 修改了合约分发逻辑,以编译后ypk作为分发的文件 + - 支持public目录下的ypk在多节点模式下执行时,合约故障自动恢复 + +- **v0.99** 2020年6月22日 + + - 自定义合约方法的计费 + - 新增了GasExample、Incentives示例 + - 在客户端实现了“校验多点结果”,并优化了结果返回的方式 + - 修复断线重连后无权限提示 + +- **v0.97** 2020年5月25日 + + - cpu等资源的计量:gas机制 + - onlineIDE.html 支持上传多个文件 + - udp方式组网进行多点执行[无定序消息] + - bdwareclient.html,修复只包含计算逻辑的调用示例生成前缀错误 + +- **v0.95** 2020年5月19日 + + - 修复了onlineIDE.html在的pathname有前缀时不能正确跳转bdwareclient的bug。 + - 修复了bdwareclient的pathname有前缀时自动提取url的bug。 + - 启用了合约的权限 + - 增加了NodePortal.html/OnlineIDE.html和bdwareclient.html中无权限时的提醒 + +- **v0.90** 2020年5月9日 + + - 更改了yjs.jar/bdserver.jar的打包方式 + - 更新了install.sh/update.sh + - onlineIDE的修改后提醒 + - onlineIDE标签页自适应宽度 + - 文件接口隔离 + +- **v0.8** 2020年4月26日 + + - 完善文档界面和优化SDK提供方式 + - 数瑞Web客户端,客户端中所有的数据处理和如何对处理后的数据进行渲染均来自合约调用,实现可信Web应用。 + +- **v0.78** 2020年4月13日 + + - 合约调用DAC示例 + - 支持动态修改IO权限 + - 支持合约状态自定义备份(定时)策略 + - 修复部分页面bug + - 日志展示优化 + - 优化账本日志展示 + - 启用部分权限访问控制 + +- **v0.7** 2020年3月25日 + + - 支持多种角色的访问控制 + - 更新了UI + +- **v0.6** 2020年2月14日 + + - 优化了合约进程间的通讯 + - 尝试接入P2P网络 + +- **v0.5** 2019年12月10日 + + - 完善了3种智能合约状态记录-回放策略 + - 支持了最简单的多点执行算法(不同步) + +- **v0.45** 2019年9月2日 + + - 初步实现PBFT算法 + +- **v0.4** 2019年5月10日 + + - 支持memory dump + +- **v0.35** 2019年4月26日 + + - 实现合约的静态分析框架 + - 支持事件的发布-订阅 + +- **v0.3** 2019年1月8日 + + - 支持账本数据的接入 + - 合约状态上链 + +- **v0.2** 2018年10月9日 + + - 支持Python包的自动生成 + - 支持合约打包为ypk + - 支持文件、数据库等数据的接入 + +- **v0.1** 2018年8月6日 + + - 定义了智能合约的语法 + - 基于nashorn引擎,实现了智能合约的执行 + +-------------- + +使用开源项目说明 +---------------- + +BDWareContract项目站在了许多巨人的肩膀上,感谢这些开源项目。 + +本项目的智能合约后端使用了以下开源库。 + +================================================================ =================================================================================================================== ================================================== +名称 Licence类型 说明 +================================================================ =================================================================================================================== ================================================== +`Project Nashorn `__ `GPLv2 `__ 使用了该项目的编译器,可以将js函数编译为java字节码 +`ASM OW2 `__ `BSD `__ with attribution 基于asm的TreeAPI与VisitorAPI实现合约的静态分析框架 +`Netty `__ `Apache License 2.0 `__ 使用netty作为Http/Websocket的服务端 +`gRPC `__ `Apache License 2.0 `__ 使用gRPC与BDWareLedger通讯 +`RocksDB `__ `GPLv2 `__ 后台数据库 +`ANTLR `__ `BSD `__ 对合约脚本的词法分析与语法分析 +`SM2Java `__ `无 `__ 国密SM2 Java语言实现 +================================================================ =================================================================================================================== ================================================== + +本项目的智能合约前端使用了以下开源库。 + +========================================================= =========================================================================== ========================== +名称 Licence类型 说明 +========================================================= =========================================================================== ========================== +`Bootstrap `__ `MIT `__ 前端的排版、样式 +`jQuery `__ `MIT `__ 用于操作DOM的javascript库 +`jQueryUI `__ `MIT `__ 前端UI构件库 +`DataTables `__ `MIT `__ 表格样式 +`CodeMirror `__ `MIT `__ 代码编辑框样式 +`eCharts `__ `ApacheV2 `__ 统计图表 +`sm-crypto `__ `MIT `__ 国密SM2 javascript语言实现 +========================================================= =========================================================================== ========================== + +本项目的文档使用\ `Sphinx `__\ 生成,感谢\ `readthedocs `__\ 提供文档样式。 diff --git a/doc/_sources/YJSAPI.rst.txt b/doc/_sources/YJSAPI.rst.txt new file mode 100644 index 0000000..e8d615f --- /dev/null +++ b/doc/_sources/YJSAPI.rst.txt @@ -0,0 +1,1574 @@ +YJS SDK +======= + +YJS Build-in API +---------------- + +内置对象 Global +~~~~~~~~~~~~~~~ + +内置对象 requester +~~~~~~~~~~~~~~~~~~ + +该内置对象在export function里面会有值,仅当合约调用签名验证通过。 + +执行合约 executeContract +~~~~~~~~~~~~~~~~~~~~~~~~ + +参数: + +.. code:: bash + + action:executeContract; + contractID:合约的id或名称均可; + operation:调用合约的方法名; + arg: 参数;格式为JSON字符串,有action与arg两个字段。 + +可选参数: + +.. code:: bash + + requestID:字符串类型,自行生成,用于查询hash + +使用示例: + +.. code:: javascript + + + function testExecutorContract(arg){ + var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg)); + if (ret.status == "Success"){ + return JSON.parse(ret.result); + }else return null; + } + +订阅事件主题 subscribe +~~~~~~~~~~~~~~~~~~~~~~ + +参数 + +.. code:: bash + + contractID:字符串类型 合约id或名称均可。 + event:字符串类型 + handler:方法名,该方法必须接受Event(内含字段topic和content)类型的唯一变量为参数;可以不是export方法 + +使用示例: + +.. code:: javascript + + export function init(arg) { + YancloudUtil.subscribe("topic", handler); + print("Handler: " + handler); + } + + function handler(e) { + print("topic: " + e.topic); + print("content: " + e.content); + } + +发布事件 pubEvent +~~~~~~~~~~~~~~~~~ + +参数 + +.. code:: bash + + topic:字符串类型,发布的事件主题 + content:字符串类型,发布的事件内容 + +使用示例: + +.. code:: javascript + + export function pub1(arg) { + YancloudUtil.pubEvent("topic", arg); + return "done"; + } + +也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件 + +.. code:: javascript + + event topic; + export function pub2(arg) { + topic(arg); + return "done"; + } + +该写法与上面的\ ``pub1``\ 等价。 + +发布带语义事件 pubEventConstraint +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +参数 + +.. code:: bash + + topic:字符串类型,发布的事件主题 + content:字符串类型,发布的事件内容 + semantics:枚举类型,作为字符串输入,事件语义 + +事件语义参数 + AT_LEAST_ONCE:至少一次,默认语义 + +AT_MOST_ONCE:至多一次 + ONLY_ONCE:只有一次 + +使用示例: + +.. code:: javascript + + export function pub1(arg) { + YancloudUtil.pubEventConstraint("topic", arg, "AT_MOST_ONCE"); + return "done"; + } + +也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名按声明的语义发布事件 + +.. code:: javascript + + event AT_MOST_ONCE topic; + export function pub2(arg) { + topic(arg); + return "done"; + } + +该写法与上面的\ ``pub1``\ 等价。 + +事先声明的事件无论是否声明语义,都可以用后缀s作为方法名的方式调用,发布任意语义的事件: + +.. code:: javascript + + event topic; + export function pub3(arg) { + topics(arg, "AT_MOST_ONCE"); + return "done"; + } + +该写法与上面的\ ``pub1, pub2``\ 等价。 + +*不带事件语义声明事件时,语义默认为至少一次(AT_LEAST_ONCE)。* + +访问资源文件 +~~~~~~~~~~~~ + +通过Global.Resources去加载ypk内部的资源文件。 + +loadAsInputStream +^^^^^^^^^^^^^^^^^ + +参数: + +.. code:: bash + + path:字符串类型 需要加载文件的地址 + +使用示例: + +.. code:: javascript + + var file = Global.Resources.loadAsInputStream("/deleteit.txt"); + +loadAsScanner +^^^^^^^^^^^^^ + +参数: + +.. code:: bash + + path:字符串类型 需要加载文件的地址 + +使用示例: + +.. code:: javascript + + var scanner = Global.Resources.loadAsScanner("/local.txt"); + +YJS Build-in Annotation +----------------------- + +@Access +~~~~~~~ + +设置合约的调用是否需要签名,这里分为两种,需签名和无签名。 +其中,“verified”表示需要签名。其他则表示无需签名。 + +:: + + @Access("verified") + export function easy(arg){ + return "true"; + } + +@LogType +~~~~~~~~ + +LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。 + +其中,Arg表示日志中记录合约执行的参数;Result表示记录合约执行的返回结果;Branch表示记录合约执行分支。 + +例如 ,通过如下LogType注解来声明函数 + +:: + + @LogType("Arg","Result","Branch") + export function easy(arg){ + Global.a = "a"; + Global.b = "b"; + if(arg > 0) + return Global.a; + else + return Global.b; + } + +@LogLocation +~~~~~~~~~~~~ + +该注解可以修饰\ ``contract``\ 或\ ``function``\ 。 +设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地,如果没有指定为“dataware”则仅存储在本地。 +例如,通过如下LogLocation设置存储位置。 + +在BaaS平台中,可以指定账本名称,BaaS平台默认账本为default,使用 +``@LogLocation("bdledger:default")``\ 。如想保存到自定义的账本,比如,“abc”账本,就使用 +``@LogLocation("bdledger:abc")`` + +:: + + @LogLocation("dataware") + export function easy(arg){ + Global.a = "a"; + } + +@Permission +~~~~~~~~~~~ + +该注解只能修饰\ ``contract`` +设置合约中调用的工具类的权限,包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类,需要在注解中添加对应的授权字段,默认只有YJS自带的YancloudUtil;如果没有添加则会抛出“未授权工具类”的异常。 +这6种工具类的详细说明在本小节后续中有说明。 + +:: + + @Permission("Http","File") + contract HttpPermission { + export function main(args){ + var http=HttpUtil.httpGet(args); + var dir="adf/adfas/"; + var file=FileUtil.getDir(dir); + return YancloudUtil.currentTimeMillis(); + } + } + +@Description +~~~~~~~~~~~~ + +该注解可以修饰\ ``contract``\ 或\ ``function``\ 。 +传入合约及函数的简介,可用于生成说明文档中关于exported函数的介绍。 + +:: + + @Description("返回数据条目,无需参数") + export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); + } + +@Param +~~~~~~ + +该注解可以修饰\ ``function``\ 。 +提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。 + +:: + + @Param({"offset":0,"count":100}) + export function get(args){ + var offset = args.offset; + var count = args.count; + ... + } + +@MockTemplate +~~~~~~~~~~~~~ + +该注解可以修饰\ ``function``\ 。 +提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时,返回按照此格式生成的模拟数据。 + +####支持的字段类型 + +:: + + @integer 整数 + @string 字符串 + @boolean 布尔值 + @date @time @datatime + @word 单词 @cword 中文单词 + @first @last 英文姓,名 + @cfirst @clast @cname 中文姓,名,全名 + @url @domin @ip @email + @region @province @city @county 地区,省,市,县 + …… + 详细格式可以参考http://mockjs.com/examples.html + +####注意:模板的格式为{‘result’:模板} + +.. code:: json + + //返回一个对象包含如下字段 + @MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}}) + //返回 + {"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"}" + + + //返回元素个数为1-5个之间的一个数组,数组的每个元素都是上述格式的一个对象 + {'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]} + //返回 + [ + {"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"}, + {"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"}, + {"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"} + ] + +:: + + @MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}}) + export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); + } + +@Result +~~~~~~~ + +该注解可以修饰\ ``function``\ 。 +提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。 + +:: + + @Result(666) + export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); + } + +IO工具类 +-------- + +概览 +~~~~ + +================================================================= ================================== +IO工具类名称 说明 +================================================================= ================================== +`FileUtil <./YJSAPI.html#fileutil>`__ 文件操作相关的类 +`LedgerUtil <./YJSAPI.html#ledgerutil>`__ 账本操作相关的类 +`HttpUtil <./YJSAPI.html#httputil>`__ Http接口相关的类 +`DOIPUtil <./YJSAPI.html#doiputil>`__ DoIP相关的类 +`MySQLUtil <./YJSAPI.html#mysqlutil>`__ 连接mysql数据库 +`MongoDBUtil <./YJSAPI.html#mongodbutil>`__ MongoDB连接相关的类 +`RocksDBUtil <./YJSAPI.html#rocksdbutil>`__ RocksDB(基于本地文件的k-v数据库) +`BDWareTimeSeriesDBUtil <./YJSAPI.html#BDWareTimeSeriesDBUtil>`__ 基于本地文件的时间序列数据库 +================================================================= ================================== + +FileUtil +~~~~~~~~ + +可以使用@Permission(“File”)来引入FileUtil对象。 + +:: + + @Permission("File") + contract FileSample { + ... + } + +该对象支持以下方法: + +copyTo +^^^^^^ + +可以复制文件和目录。第一个参数是source,第二个参数是destination。 + +参数 +'''' + +==== ==== ============ +序号 参数 说明 +==== ==== ============ +1 src 类型为String +2 dest 类型为String +==== ==== ============ + +使用示例 +'''''''' + +.. code:: javascript + + var ret = FileUtil.copyTo("./source.txt","./dest.txt"); + +getContent +^^^^^^^^^^ + +获取文件的文本内容,当文件不存在时,返回\ ``undefined``\ 。 + +.. _参数-1: + +参数 +'''' + +==== ==== ============ +序号 参数 说明 +==== ==== ============ +1 path 类型为String +==== ==== ============ + +.. _使用示例-1: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = FileUtil.getContent("./source.txt"); + +getDir +^^^^^^ + +获取文件所在的文件夹名,输入参数为字符串。 + +.. _参数-2: + +参数 +'''' + +==== ==== ============ +序号 参数 说明 +==== ==== ============ +1 path 类型为String +==== ==== ============ + +.. _使用示例-2: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = FileUtil.getDir("./parent/src.txt"); + // ret 为 "./parent/"; + +getFileName +^^^^^^^^^^^ + +获取文件名。输入参数为字符串。 + +.. _参数-3: + +参数 +'''' + +==== ==== ============ +序号 参数 说明 +==== ==== ============ +1 path 类型为String +==== ==== ============ + +.. _使用示例-3: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = FileUtil.getFileName("./parent/src.txt"); + // ret 为 "src.txt" + +openFileAsPrinter +^^^^^^^^^^^^^^^^^ + +以PrintStream的形式打开文件。 +返回结果是\ ``java.io.PrintStream``\ 类型。 + +.. _参数-4: + +参数 +'''' + +==== ======== ===================================== +序号 参数 说明 +==== ======== ===================================== +1 path 文件名,类型为String +2 isAppend 类型为boolean,表示是否往文件末尾添加 +==== ======== ===================================== + +.. _使用示例-4: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true); + ret.println("hello"); + ret.close(); + +LedgerUtil +~~~~~~~~~~ + +可以使用@Permission(“Ledger”)来引入LedgerUtil对象。 + +:: + + @Permission("Ledger") + contract LedgerExample{ + ... + } + +getClient +^^^^^^^^^ + +获取一个连接客户端,一个参数,为对象类型。 +返回结果为LedgerClient类型,用于后续的查询账本等操作。 + +.. _参数-5: + +参数 +'''' + +==== ======= ==================== +序号 参数 说明 +==== ======= ==================== +1 address 包含ip和端口两个字段 +==== ======= ==================== + +.. _使用示例-5: + +使用示例 +'''''''' + +.. code:: javascript + + var address = {}; + address.ip = "127.0.0.1"; + address.port = 18091; + var ledgerClient = LedgerUtil.getClient(address); + +queryByHash +^^^^^^^^^^^ + +根据Hash查询Transaction。 +返回结果为对象,包含from、to、type和data四个字段,均为String类型。 +其中data为按utf-8编码解析字节数组,如果存证时用的不是utf8编码,可能返回乱码。 + +.. _参数-6: + +参数 +'''' + +==== ====== ================================================ +序号 参数 说明 +==== ====== ================================================ +1 client 通过getClient方法获得的对象 +2 info 对象类型,有两个字段ledger和hash,均为字符串类型 +==== ====== ================================================ + +.. _使用示例-6: + +使用示例 +'''''''' + +.. code:: javascript + + // ... ledgerClient = LedgerUtil.getClient(...); + var info = {}; + info.ledger = "bdcontract"; + info.hash = "4d3b75750835092a50085127702669615b602e53"; + var ret = LedgerUtil.queryByHash(ledgerClient,info); + print(ret.from); + print(ret.to); + print(ret.type); + print(ret.data); + +sendTransaction +^^^^^^^^^^^^^^^ + +存证数据。 + +.. _参数-7: + +参数 +'''' + +==== ====== ========================================================================== +序号 参数 说明 +==== ====== ========================================================================== +1 client 通过getClient方法获得的对象 +2 info 对象类型,有from:raw-latex:`\to`:raw-latex:`\data三个字段`,均为String类型 +==== ====== ========================================================================== + +.. _使用示例-7: + +使用示例 +'''''''' + +.. code:: javascript + + // ... ledgerClient = LedgerUtil.getClient(...); + var info = {}; + info.ledger = "bdcontract"; + info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155"; + info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155"; + info.data = "hello world"; + var ret = LedgerUtil.sendTransaction(ledgerClient,info); + //ret为存证的哈希值 + print(ret); + +HttpUtil +~~~~~~~~ + +可以使用@Permission(“Http”)来引入HttpUtil对象。 + +:: + + @Permission("Http") + contract HttpExample{ + ... + } + +createAPIGate +^^^^^^^^^^^^^ + +配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。 + +.. _参数-8: + +参数 +'''' + +==== ==== ============================== +序号 参数 说明 +==== ==== ============================== +1 ip 字符串类型,ip,端口默认为6161 +==== ==== ============================== + +.. _使用示例-8: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = HttpUtil.createAPIGate("192.168.4.4"); + ret.get("com.tencent.mm","sendMsg","msg"); + print(ret); + +.. _createapigate-1: + +createAPIGate +^^^^^^^^^^^^^ + +配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。 + +.. _参数-9: + +参数 +'''' + +==== ==== ================ +序号 参数 说明 +==== ==== ================ +1 ip 字符串类型,ip +2 port 字符串类型,端口 +==== ==== ================ + +.. _使用示例-9: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = HttpUtil.createAPIGate("192.168.4.4", "6161"); + ret.get("com.tencent.mm","sendMsg","msg"); + print(ret); + +get +^^^ + +发起Http的get请求。 +返回结果为对象类型,包含response和responseCode两个字段。 + +.. _参数-10: + +参数 +'''' + +==== ==== =================== +序号 参数 说明 +==== ==== =================== +1 url 字符串,表示url类型 +==== ==== =================== + +.. _使用示例-10: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = HttpUtil.get("https://www.baidu.com"); + print(ret.responseCode); + print(ret.response); + +post +^^^^ + +发起Http的post请求。 +返回结果为对象类型,包含response和responseCode两个字段。 + +.. _参数-11: + +参数 +'''' + +==== ==== ====================================================================== +序号 参数 说明 +==== ==== ====================================================================== +1 args 对象类型,有url,headers和data三个字段。其中,args.headers为对象类型。 +==== ==== ====================================================================== + +.. _使用示例-11: + +使用示例 +'''''''' + +.. code:: javascript + + var req = {}; + req.url = "https://www.baidu.com"; + req.data = "hello"; + req.header = {}; + req.header.Accept = "application/json"; + req.header["Content-Type"] = "application/json"; + var ret = HttpUtil.post(req); + print(ret.resposeCode); + print(ret.response); + +DOIPUtil +~~~~~~~~ + +可以使用@Permission(“DOIP”)来引入DOIPUtil对象。 + +:: + + @Permission("DOIP") + contract DOIPExample{ + ... + } + +call +^^^^ + +调用一个DO + +.. _参数-12: + +参数 +'''' + +==== ==== ========================== +序号 参数 说明 +==== ==== ========================== +1 arg0 字符串类型, 目标DO标识 +2 arg1 字符串类型, 输入参数字符串 +==== ==== ========================== + +.. _使用示例-12: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.call("86.5000.470/do.hello","inputString"); + +create +^^^^^^ + +向一个Repository创建一个字符串类型DO + +.. _参数-13: + +参数 +'''' + +==== ==== ============================ +序号 参数 说明 +==== ==== ============================ +1 arg0 字符串类型, 目标Repo标识 +2 arg1 对象类型,包括doID,doBody字段 +==== ==== ============================ + +.. _使用示例-13: + +使用示例 +'''''''' + +.. code:: javascript + + var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}"); + var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject); + +delete +^^^^^^ + +从一个Repository中删除DO + +.. _参数-14: + +参数 +'''' + +==== ==== ======================= +序号 参数 说明 +==== ==== ======================= +1 arg0 字符串类型 目标DO标识 +2 arg1 字符串类型 目标Repo标识 +==== ==== ======================= + +.. _使用示例-14: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo"); + +hello +^^^^^ + +获取目标Repository的DOIP服务信息 + +.. _参数-15: + +参数 +'''' + +==== ==== ======================= +序号 参数 说明 +==== ==== ======================= +1 arg0 字符串类型 目标Repo标识 +==== ==== ======================= + +.. _使用示例-15: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo"); + +listOperation +^^^^^^^^^^^^^ + +获取目标DO支持的DOIP操作 + +.. _参数-16: + +参数 +'''' + +==== ==== ===================== +序号 参数 说明 +==== ==== ===================== +1 arg0 字符串类型 目标DO标识 +==== ==== ===================== + +.. _使用示例-16: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.listOperation("86.5000.470/do.hello"); + +register +^^^^^^^^ + +向LHS注册一个DO,返回分配的标识 + +.. _参数-17: + +参数 +'''' + +==== ==== =========================== +序号 参数 说明 +==== ==== =========================== +1 arg0 字符串类型 DO所在Repo标识 +2 arg1 字符串类型 DO格式描述字符串 +==== ==== =========================== + +.. _使用示例-17: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String"); + +reregister +^^^^^^^^^^ + +修改LHS中DO的注册信息 + +.. _参数-18: + +参数 +'''' + +==== ==== =========================== +序号 参数 说明 +==== ==== =========================== +1 arg0 字符串类型 目标DO标识 +2 arg1 字符串类型 DO所在Repo标识 +3 arg2 字符串类型 DO格式描述字符串 +==== ==== =========================== + +.. _使用示例-18: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String"); + +retrieve +^^^^^^^^ + +获取一个DO + +.. _参数-19: + +参数 +'''' + +==== ==== ===================== +序号 参数 说明 +==== ==== ===================== +1 arg0 字符串类型 目标DO标识 +==== ==== ===================== + +.. _使用示例-19: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.retrieve("86.5000.470/do.hello"); + +test +~~~~ + +测试DOIPUtils是否可用 ##### 参数 + +==== ==== ===================== +序号 参数 说明 +==== ==== ===================== +1 arg0 字符串类型 任意字符串 +==== ==== ===================== + +.. _使用示例-20: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = DOIPUtil.test("hello"); + +update +^^^^^^ + +更新目标DO + +.. _参数-20: + +参数 +'''' + +==== ==== ========================== +序号 参数 说明 +==== ==== ========================== +1 arg0 JS对象,包括doID,doBody字段 +==== ==== ========================== + +.. _使用示例-21: + +使用示例 +'''''''' + +.. code:: javascript + + var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}"); + var ret = DOIPUtil.update(digitalObject); + +SQLUtil +~~~~~~~ + +可以使用@Permission(“SQL”)来引入SQLUtil对象。 +可支持MySQL/PostgreSQL/Oracle/GuassDB200等SQL数据库。 +需要将对应的jdbc的jar上传到项目中。 +例如,要使用mysql,可上传mysql-connector-java-8.0.24.jar + +:: + + @Permission("SQL") + oracle MySQLExample{ + ... + } + +initDriver +^^^^^^^^^^ + +.. _参数-21: + +参数 +'''' + +==== =========== ========== +序号 参数 说明 +==== =========== ========== +1 driverClass 字符串类型 +==== =========== ========== + +.. _使用示例-22: + +使用示例 +'''''''' + +.. code:: javascript + + //使用mysql + SQLUtil.initDriver("com.mysql.cj.jdbc.Driver"); + //使用postgresql + SQLUtil.initDriver("org.postgresql.Driver"); + //使用oracle + SQLUtil.initDriver("oracle.jdbc.OracleDriver"); + +getConnection +^^^^^^^^^^^^^ + +.. _参数-22: + +参数 +'''' + +==== ======= ==================== +序号 参数 说明 +==== ======= ==================== +1 URL 字符串类型,jdbc连接 +2 usrName 字符串类型,用户名 +3 pwd 字符串类型,密码 +==== ======= ==================== + +.. _使用示例-23: + +使用示例 +'''''''' + +.. code:: javascript + + var url = "jdbc:mysql://xx.xx.xx:port/tableName"; + var usrName = "xxx"; + var pwd = "xxx"; + //配置好用户名和密码,url格式为ip或域名+端口,中间以”:”隔开。 + var conn = SQLUtil.getConnection(url,usrName,pwd); + //获取数据库连接 + var sql = "select * from newele.data"; + //创建查询语句 + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var waimailist = []; + //解析查询结果 + var meta = resultSet.getMetaData(); + for (;resultSet.next();){ + var line = {}; + for (var j=1;j<=meta.getColumnCount();j++){ + line[meta.getColumnName(j)] = resultSet.getString(j); + } + waimailist.push(line); + } + +其中,getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此,可以查看: +https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html +以了解如何进行Mysql数据库操作。 + +MongoDBUtil +~~~~~~~~~~~ + +可以使用@Permission(“MongoDB”)来引入MongoDBUtil对象。 + +:: + + @Permission("MongoDB") + contract MongoDBExample{ + ... + } + +.. _getconnection-1: + +getConnection +^^^^^^^^^^^^^ + +.. _参数-23: + +参数 +'''' + +==== ======= ========================= +序号 参数 说明 +==== ======= ========================= +1 URL 字符串类型 数据库的URL +2 port 整数类型 端口号 +3 dbName 字符串类型 数据库的名称 +4 usrName 字符串类型 数据库的用户名 +5 pwd 字符串类型 数据库的密码 +==== ======= ========================= + +.. _使用示例-24: + +使用示例 +'''''''' + +**注意:port为整型,其他参数为String类型** + +.. code:: javascript + + var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd); + //获取数据库对象 + var db = client.getDatabase("yancloud"); + var collection = db.getCollection("containers"); + var iter = collection.find().iterator(); + var ret =""; + for (;iter.hasNext();){ + ret+=iter.next().toJson(); + ret+="\n"; + } + +其中,getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此,可以查看: +https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClient.html + +以了解该对象的更多方法和使用方式。 + +RocksDBUtil +~~~~~~~~~~~ + +使用@Permission(“RocksDB”)来引入RocksDBUtil对象。 + +:: + + @Permission("RocksDB") + contract RocksDBSample { + ... + } + +loadDB +^^^^^^ + +通过loadDB来加载一个RocksDB数据库。 加载后,可进行get/delete/put等操作。 + +.. _参数-24: + +参数 +'''' + +==== ======== =========================== +序号 参数 说明 +==== ======== =========================== +1 path 字符串类型 数据库部署的路径 +2 readOnly 布尔类型 数据库只读 +==== ======== =========================== + +.. _使用示例-25: + +使用示例 +'''''''' + +:: + + @Permission("RocksDB") + @Description("这是个使用RocksDB的参考代码") + contract RocksDBSample{ + function onCreate(){ + Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false"); + } + @Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}") + export function put(arg){ + arg = JSON.parse(arg); + Global.rocksdb.put(arg.key,arg.value); + return "success"; + } + @Description("示例参数: \"abc\"}") + export function get(arg){ + return Global.rocksdb.get(arg); + return "failed"; + } + @Description("示例参数: \"abc\"") + export function deleteKey(arg){ + return Global.rocksdb.delete(arg); + } + @Description("遍历KV库,无需参数") + export function iter(arg){ + var iter = Global.rocksdb.newIterator(); + var obj = undefined; + var ret = { + }; + for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){ + ret[obj.key]=obj.value; + } + return JSON.stringify(ret) + } + } + +BDWareTimeSeriesDBUtil +~~~~~~~~~~~~~~~~~~~~~~ + +使用示例 + +:: + + @Permission("BDWareTimeSeriesDB") + contract BDWareTimeDBExample{ + function onCreate(arg){ + Global.dbutil = BDWareTimeSeriesDBUtil.getConnection(); + } + + export function put(arg){ + //第一个参数为表名,第二个参数为要放的value,时间戳自动打。 + Global.dbutil.put("defaultTable",arg); + return "success"; + } + @Param + export function getCount(arg){ + return Global.dbutil.getCount("defaultTable"); + } + @Param(1617254937373) + export function queryByStartTime(arg){ + var startDate = java.lang.Long.valueOf(arg); + //查询从开始时刻startDate到最新的数据 + var list = Global.dbutil.query("defaultTable",startDate); + var ret=[]; + print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size()); + var i=0; + for (i=0;i"+list.get(i)); + ret.push(list.get(i)); + } + return ret; + } + + @Description("示例参数: {\"offset\":1,\"len\":1}") + @Param({"offset":1,"len":1}) + export function queryByOffset(arg){ + var offsetLen = JSON.parse(arg); + //可配合getCount使用,查询第offset至offset+len条数据 + var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len); + var ret=[]; + print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size()); + var i=0; + for (i=0;i"+list.get(i)); + ret.push(list.get(i)); + } + return ret; + } + } + +加解密工具类 +------------ + +SM2 +~~~ + +可以使用@Permission(“SM2”)来引入SM2Util对象。 + +:: + + @Permission("SM2") + contract SM2Sample { + ... + } + +generateKeyPair +^^^^^^^^^^^^^^^ + +生成公私钥。 + +.. _参数-25: + +参数 +'''' + +无参数。 + +.. _使用示例-26: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = SM2Util.generateKeyPair(); + print(ret.publicKey); + print(ret.privateKey); + return JSON.stringify(ret); + +sign +^^^^ + +签名。 + +.. _参数-26: + +参数 +'''' + +==== ======= =========================== +序号 参数 说明 +==== ======= =========================== +1 content 字符串类型 要进行签名的内容 +2 keyPair sm2 +==== ======= =========================== + +.. _使用示例-27: + +使用示例 +'''''''' + +:: + + var keypair = SM2Util.generateKeyPair(); + var ret = SM2Util.sign("Hello",keypair); + print(ret.status); + //如果status是success + print(ret.signature); + //如果status是failed + print(ret.message); + +verify +^^^^^^ + +验签。 + +.. _参数-27: + +参数 +'''' + +==== ========= ======================= +序号 参数 说明 +==== ========= ======================= +1 content 字符串类型 待验签的内容 +2 signature 字符串类型 签名 +3 publicKey 字符串类型 公钥 +==== ========= ======================= + +.. _使用示例-28: + +使用示例 +'''''''' + +.. code:: javascript + + var ret = SM2Util.verify("Hello","....签名","...公钥"); + // 验证通过时,result为true,status为success + // 失败时,result为failed,status为failed + print(ret.status); + print(ret.result); + +多线程工具类 +------------ + +AsyncUtil +~~~~~~~~~ + +可以使用@Permission(“Async”)来引入AsyncUtil对象。 + +:: + + @Permission("Async") + contract AsyncExample{ + export function longTimeTask(arg){ + var a = { + }; + a.count = 100; + AsyncUtil.postFunction(taskFun,a); + } + function taskFun(arg){ + Global.progress = 0; + for (var i=0;i`__\ 中渲染。 +首先在合约中import以下模块。 + +.. code:: javascript + + module Viewable{ + export function loadResource(arg){ + return Global.Resources.loadAsString(arg); + } + export function needRender(arg){ + return true; + } + } + +同时,import以后,定义一个getMainFrame方法,以便数瑞客户端识别主页: + +.. code:: javascript + + export function getMainFrame(arg){ + return "/html/main.html"; + } + +该方法的返回结果为一个资源文件的路径。 +示例的资源文件“/html/main.html”如下: + +.. code:: html + +
+ Data from contract: + + + +
+ +示例的资源文件“/html/hello.js”如下: + +.. code:: javascript + + var queryDataFromContract = function(){ + //第一个参数为函数名,第二个为参数,第三个参数为回调。 + var data = executeCurrentContract("query","abc",function(argg){ + $("#resultText")[0].innerHTML = argg.result; + }); + } + +参考示例: + +YJS-Python +~~~~~~~~~~ + +TODO diff --git a/doc/_sources/index.rst.txt b/doc/_sources/index.rst.txt new file mode 100644 index 0000000..06a22c5 --- /dev/null +++ b/doc/_sources/index.rst.txt @@ -0,0 +1,18 @@ +.. BDContract documentation master file, created by + sphinx-quickstart on Mon Nov 25 16:23:38 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +北大数瑞大数据区块链 文档 +====================================== + +.. toctree:: + :maxdepth: 3 + :caption: 目录 + + Introduction.rst + InstallTips.rst + IDEUsage.rst + ContractAPI.rst + YJSInDepth.rst + YJSAPI.rst \ No newline at end of file diff --git a/doc/_sources/markdown/ContractAPI.md.txt b/doc/_sources/markdown/ContractAPI.md.txt new file mode 100644 index 0000000..ad17739 --- /dev/null +++ b/doc/_sources/markdown/ContractAPI.md.txt @@ -0,0 +1,3551 @@ +# BDContract SDK +除使用可视化的智能合约在线IDE外,用户还可使用WebSocket接口、Http接口、Bash接口来启动和运行合约. + +- - - + +## WebSocketSDK下载与安装 +合约SDK提供javascript版本与java版本的客户端。 + +java客户端的下载链接为:[java source](./_static/BDWareJavaClient.zip)和[jar](./_static/BDWareConfigTool.zip) +可参考java_source下的README.md及测试用例。 + +javascript的下载链接为:[js SDK](./_static/js/createWS.js) +内置的SM2加密库链接:[sm2 SDK](./_static/js/sm2.js) + +### 建立连接 +建立与节点服务器之间的WebSocket连接. + +#### 参数 + +| 字段 | 值 | +| ---------- | ------------------------------------------------------------ | +| url | 建立WebSocket的服务器URL. 使用`http`协议时, 前缀为`ws://`, 如`"ws://localhost:1717/SCIDE/SCExecutor"`; 使用`https`协议时, 前缀为`wss://` | +| msgHandler | 收到服务器WebSocket回复后的回调函数, 用户可自行编写, 也可参考下面提供的示例 | + +#### 请求示例 + +```javascript +var url = "ws://127.0.0.1:1717/SCIDE/SCExecutor";//与Slave节点建立连接 +//var url = "ws://127.0.0.1:1718/NodeCenterWS";//与Manager节点建立连接 +var msgHandler = function(m){ + console.log("recmsg:"); + console.log(m); +}; +var onOpenHandler=undefined; +wssocket = createWssocket(url,onOpenHandler,msgHandler); +``` + +#### 返回结果示例 + +``` +{ + receiveSeg: [Function (anonymous)], + isSending: false, + sendList: [], + monitor: [Function (anonymous)], + send: [Function (anonymous)], + sendNextSegment: [Function (anonymous)], + isOpen: [Function (anonymous)] +} +``` + + + +### ping + +`ping`服务器测试 + +#### 参数 + +| 字段 | 值 | +| ------ | ---- | +| action | ping | + +#### 请求示例 + +``` +var request = {}; +request.action = "ping"; +wssocket.send(JSON.stringify(request)); +``` + +#### 返回结果示例 + +``` +{ + "action":"pong" +} +``` + +### 登录 + +使用Websocket接口调用需要权限的接口时,不论是连接CenterPortal还是NodePortal必须先**登录**。 +登录的流程有3步: + +- 客户端向服务端建立连接,连接建立完成后发送{"action":"getSessionID"}(可在onOpenHandler中实现) +- 服务端收到请求后,会向客户端返回类似{"action":"onGetSessionID","session":"-4959947809200104526_session"}的结果 +- 客户端收到onGetSessionID后,会使用本地的公私钥对sessionID进行签名,并调用login接口 +- 服务端会返回onLogin的结果,data字段返回的是该公钥对应的角色。 + +- - - + +## 用户角色划分 + +### 合约节点的角色划分 + +在合约节点(NodePortal.html)中分为NodeManager/ContractProvider/ContractInstanceManager/ContractUser四类角色。 + +| 角色 | 说明 | +| ----------------------- | ------------------------------------------------------------ | +| NodeManager | 该节点的管理者,拥有用户管理、节点配置等权限 | +| ContractProvider | 拥有编辑合约、开发合约代码、运行调试等权限 | +| ContractInstanceManager | 拥有启、停合约实例、配置合约实例IO等权限 | +| ContractUser | 拥有查看合约实例列表、调用合约等权限 | +| Anonymous | 匿名用户,可以调用合约,可以申请成为ContractProvider/InstanceManager等角色 | + + +| 接口 | 说明 | 角色 | +| ------------------------------- | -------------------- | ----------------------------------------- | +| changeDumpPeriod | 设置备份周期 | ContractInstanceManager; | +| createLedger | 创建账本 | ContractInstanceManager; | +| dumpContract | 手动备份 | ContractInstanceManager; | +| deleteMemoryFile | 删除镜像 | ContractInstanceManager; | +| forkContract | 迁移合约 | ContractInstanceManager; | +| getDumpPeriod | 获取备份周期 | ContractInstanceManager; | +| killAllContract | 停止全部实例 | ContractInstanceManager; | +| killContractProcess | 停止某一实例 | ContractInstanceManager; | +| listMemoryFiles | 列取某一实例的镜像 | ContractInstanceManager; | +| loadMemory | 加载镜像 | ContractInstanceManager; | +| queryContractInstanceDOI | 查询合约实例信息 | ContractInstanceManager; | +| rebuildHashIndex | | ContractInstanceManager; | +| setPermission | | ContractProvider;ContractInstanceManager; | +| startContract | 启动合约 | ContractInstanceManager; | +| startContractBatched | 废弃 | ContractInstanceManager; | +| startContractByYPK | 启动合约 | ContractInstanceManager; | +| startContractInTempZips | 废弃 | ContractInstanceManager; | +| startContractConfig | 启动合约(集群模式) | ContractInstanceManager; | +| updateContract | | ContractInstanceManager; | +| connectTo | 连接合约实例输出流 | ContractInstanceManager;ContractUser; | +| countContractLogGroupByAction | | ContractInstanceManager;ContractUser; | +| countContractLogGroupByCategory | | ContractInstanceManager;ContractUser; | +| getLastLog | 查询日志 | ContractInstanceManager;ContractUser; | +| getLog | 查询日志 | ContractInstanceManager;ContractUser; | +| getLogSize | 查询日志 | ContractInstanceManager;ContractUser; | +| listAllContractProcess | | ContractInstanceManager;ContractUser; | +| listContractProcess | 查询合约实例列表 | ContractInstanceManager;ContractUser; | +| listLeakContractProcess | | ContractInstanceManager;ContractUser; | +| queryContractLogByDate | | ContractInstanceManager;ContractUser; | +| queryContractLogByKey | | ContractInstanceManager;ContractUser; | +| queryContractLogByOffset | | ContractInstanceManager;ContractUser; | +| queryContractLogDetail | | ContractInstanceManager;ContractUser; | +| queryContractLogSize | | ContractInstanceManager;ContractUser; | +| queryNodeLogByDate | | ContractInstanceManager;ContractUser; | +| queryNodeLogByOffset | | ContractInstanceManager;ContractUser; | +| queryNodeLogSize | | ContractInstanceManager;ContractUser; | +| rebuildContractLogIndex | | ContractInstanceManager;ContractUser; | +| rebuildNodeLogIndex | | ContractInstanceManager;ContractUser; | +| changePublic | | ContractProvider; | +| createFile | 新建文件 | ContractProvider; | +| deleteFile | 删除文件 | ContractProvider; | +| distributeContract | | ContractProvider; | +| downloadContract | | ContractProvider; | +| downloadContractFromOtherHost | | ContractProvider; | +| generateAnnotationSample | | ContractProvider; | +| generateAppDataAnalysis | | ContractProvider; | +| generateAppDataSource | | ContractProvider; | +| generateBDCoinEventProject | | ContractProvider; | +| generateBDCoinProject | | ContractProvider; | +| generateBiddingExample | | ContractProvider; | +| generateCSVProject | | ContractProvider; | +| generateContractExecutor | | ContractProvider; | +| generateDAC4BDOA | | ContractProvider; | +| generateDAC4BDOA_persist | | ContractProvider; | +| generateDACSample | | ContractProvider; | +| generateEmptyProject | | ContractProvider; | +| generateEventPublisher | | ContractProvider; | +| generateEventSubscriber | | ContractProvider; | +| generateGasExample | | ContractProvider; | +| generateHello | | ContractProvider; | +| generateHttpExample | | ContractProvider; | +| generateIncentives | | ContractProvider; | +| generateJSONExample | | ContractProvider; | +| generateLedgerExample | | ContractProvider; | +| generateLedgerProject | | ContractProvider; | +| generateLicenceManager | | ContractProvider; | +| generateLoggerExample | | ContractProvider; | +| generateMySQLExample | | ContractProvider; | +| generateMySQLProject | | ContractProvider; | +| generatePostgreSQLSample | | ContractProvider; | +| generateReadme | | ContractProvider; | +| generateRenderSample | | ContractProvider; | +| generateRocksDBSample | | ContractProvider; | +| generateSM2Example | | ContractProvider; | +| generateStaticResource | | ContractProvider; | +| generateTFLinux | | ContractProvider; | +| generategenerateTFMac | | ContractProvider; | +| getProject | | ContractProvider; | +| getTemplateList | | ContractProvider; | +| importContractInstanceCodeByDOI | | ContractProvider; | +| listFile | | ContractProvider; | +| listProject | | ContractProvider; | +| listProjectPermission | | ContractProvider; | +| listProjects | | ContractProvider; | +| renameFile | | ContractProvider; | +| saveFile | | ContractProvider; | +| startContractAsDebug | | ContractProvider; | +| uploadFile | | ContractProvider; | +| compile | | ContractProvider;ContractInstanceManager; | +| evaluates | | ContractProvider;ContractInstanceManager; | +| executeContractP2PTrustfully | | ContractProvider;ContractInstanceManager; | +| getCodeByID | 查询代码 | ContractProvider;ContractInstanceManager; | +| getControlFlowByFileName | | ContractProvider;ContractInstanceManager; | +| getGasValue | | ContractProvider;ContractInstanceManager; | +| listCompiledFiles | | ContractProvider;ContractInstanceManager; | +| queryContractResourceInfo | | ContractProvider;ContractInstanceManager; | +| queryFreeResourceInfo | | ContractProvider;ContractInstanceManager; | +| staticVerifyContract | | ContractProvider;ContractInstanceManager; | +| writeDyjs | | ContractProvider;ContractInstanceManager; | +| authNodeRole | 授权角色 | NodeManager; | +| changeBDledger | 修改账本配置 | NodeManager; | +| changeIpPort | | NodeManager; | +| changeNodeCenter | 修改集群地址 | NodeManager; | +| changeNodeName | | NodeManager; | +| changeIpPort | | NodeManager; | +| changeDOIPConfig | | NodeManager; | +| changeYJSPath | | NodeManager; | +| countNodeLogGroupByCategory | | NodeManager; | +| countRole | | NodeManager; | +| deleteRole | | NodeManager; | +| downloadUUID | 废弃 | NodeManager; | +| getEncodedUUID | 废弃 | NodeManager; | +| getPeerID | | NodeManager; | +| listAllAuthRole | | NodeManager; | +| listNodeInfos | | NodeManager; | +| listUnAuthRole | | NodeManager; | +| loadConfig | | NodeManager; | +| loadNodeConfig | | NodeManager; | +| lockEdit | | NodeManager; | +| unlockEdit | | NodeManager; | +| updateConfig | | NodeManager; | +| uploadLicence | | NodeManager; | +| applyNodeRole | 申请角色 | 任意角色 | +| executeContract | 调用合约 | 任意角色 | +| getConnCount | | 任意角色 | +| getHashAbstractLocally | | 任意角色 | +| getHashLocally | | 任意角色 | +| getNodeRoleDeprecated | 查询当前角色 | 任意角色 | +| getSessionID | | 任意角色 | +| listAdapters | | 任意角色 | +| listTheContractProcess | | 任意角色 | +| login | 登录 | 任意角色 | +| longStr | | 任意角色 | +| ping | | 任意角色 | +| queryDataByHash | | 任意角色 | +| queryDataByHashLocally | | 任意角色 | +| queryHashByOffset | | 任意角色 | +| queryHashByRequestID | | 任意角色 | +| queryHashSize | | 任意角色 | +| queryLedgers | | 任意角色 | +| queryRole | | 任意角色 | +| queryTransactionByHash | | 任意角色 | +| sendTransaction | | 任意角色 | +| setLogStage | | 任意角色 | + +### 合约准入中心角色划分 + +共分为两类角色:CenterManager和NodeManager。其中,CenterManager拥有对集群设置的权限。 +NodeManager可以增加、删除节点等操作。 + +| 接口 | 说明 | 角色 | +| ----------------------------- | ------------ | -------------------------- | +| authNodeManager | | CenterManager; | +| countActionLogByCategory | | CenterManager; | +| countCMLogByCategory | | CenterManager; | +| delete | | CenterManager; | +| listAllUsers | | CenterManager; | +| listApplyList | | CenterManager; | +| listLicence | | CenterManager; | +| queryActionLog | | CenterManager; | +| queryCMLog | | CenterManager; | +| updateLicence | | CenterManager; | +| addNode | | CenterManager;NodeManager; | +| changeNCFile | | CenterManager;NodeManager; | +| changeOtherNC | | CenterManager;NodeManager; | +| createTrustUnit | 创建可信集群 | CenterManager;NodeManager; | +| deleteTrustUnit | | CenterManager;NodeManager; | +| getNCFile | | CenterManager;NodeManager; | +| getNodeTrustUnits | | CenterManager;NodeManager; | +| getOtherNC | | CenterManager;NodeManager; | +| listContractProcess | | CenterManager;NodeManager; | +| listMultiPointContractProcess | | CenterManager;NodeManager; | +| listNodes | | CenterManager;NodeManager; | +| listTrustUnits | | CenterManager;NodeManager; | +| queryUserStat | | CenterManager;NodeManager; | +| stopMultiPointContractProcess | | CenterManager;NodeManager; | +| applyRole | | NodeManager; | +| executeContract | 调用合约 | 任意角色 | +| executeContractTrustfully | | 任意角色 | +| getManagerPubkey | | 任意角色 | +| getNodeRole | | 任意角色 | +| getNodeSessionID | | 任意角色 | +| getRole | | 任意角色 | +| getSessionID | | 任意角色 | +| login | 登录 | 任意角色 | + +- - - + +## 合约节点Http接口 + +`http://xxx.xxx.xxx.xxx:1717/SCIDE/SCManager`为提供Http接口服务的服务器 URL(`xxx.xxx.xxx.xxx:1717`为BDWare SCIDE运行的IP和端口号) , 用户可通过在URL后附加字段参数, 完成以下功能. +`http://xxx.xxx.xxx.xxx:18000/SCIDE/SCManager` 为提供Http接口服务的服务器 + +URL(`xxx.xxx.xxx.xxx:1717` 为BDWare SCIDE运行的IP和端口号),用户可通过在URL后附加字段参数,完成以下功能: + + +### 用户管理类 + +#### ping + +`ping`服务器测试 + +##### 方法 + +GET + +##### 参数 + + +| 字段 | 值 | +| ------ | ---- | +| action | ping | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=ping +``` + +##### 返回结果示例 + +```json +{"data":"pong"} +``` + + +### 合约代码管理类 + + +#### 下载合约项目 + +##### 方法 + +GET + +##### 参数 + + +| 字段 | 值 | +| ----------- | ---------------- | +| action | downloadContract | +| projectName | 合约项目名 | +| isPrivate | 是否在私有目录下 | +| pubKey | 用户公钥 | +| timestamp | 时间戳 | +| sign | 签名 | + + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=downloadContract&projectName=BDCoin&isPrivate=false&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3 +8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275 +``` + +#### 上传文件 + +##### 方法 + +POST + + +##### 参数 + + +| 字段 | 值 | +| --------- | ---------------- | +| path | 文件上传路径 | +| fileName | 待上传文件名 | +| isPrivate | 是否在私有目录下 | +| order | 第几个数据包 | +| count | 数据包总数 | +| timestamp | 时间戳 | +| sign | 签名 | + + +##### 请求示例 + + +``` +http://127.0.0.1:18000/SCIDE/Upload?path=/TEST/TEST.yjs&fileName=WechatIMG15.jpeg&isPrivate=true&order=0&count=3&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05&sign=dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275 +``` + +##### 返回结果示例 + +```json +{"status":"true","data":"success"} +``` + +#### 保存合约脚本 + +向服务器发送请求, 向服务器本地保存合约脚本内容. + +##### 方法 + +GET + + +##### 参数 + +| 字段 | 值 | +| ------- | -------------- | +| action | writeDyjs | +| target | 合约脚本文件名 | +| content | 合约脚本内容 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=writeDyjs&target=testyjs.yjs&content=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "action": "onWriteDyjs", + "data": "success" +} +``` + +后续用户可启动并调用该合约. + + + + + + + +### 合约实例管理类 + +#### 查询合约进程 + +向服务器发送请求, 查询服务器上已经启动的所有合约进程. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------- | +| action | listContractProcess | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=listContractProcess +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "action": "onListContractProcess", + "data": "[\n {\n \"id\": \"-562752842\",\n \"name\": \"shortc\",\n \"port\": \"1626\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n }\n]" +} +``` + + +#### 启动合约 + +向服务器发送请求, 启动某个合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------------------- | +| action | startContract | +| script | 合约脚本内容, 需进行进行URIEncode | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=startContract&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D +``` + +##### 返回结果示例 + +```json +{ + "data": "{\"status\":\"Success\",\"result\":\"\"}", + "action": "onStartContract", + "cid": "-562752842", + "executeTime": 1187 +} +``` + + + +#### 调用合约 + +向服务器发送请求, 调用某个合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------------------- | --------------------------- | +| action | executeContract | +| contractID | 合约ID | +| withDynamicAnalysis | true/false 是否进行动态分析 | +| operation | 调用合约的方法名 | +| arg | 调用合约的参数 | +| pubkey | 可选,调用者公钥 | +| signature | 可选,签名 | + + +其中pubkey为sm2的公钥,计算方式如下: + +```javascript +//sm2 可从sm2.js中加载获得。 +signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey); +``` + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=executeContract&contractID=-620602333&operation=main&arg=hhh +``` + +##### 返回结果示例 + +```json +{ + "data": "{\"status\":\"Success\",\"result\":\"3\"}", + "action": "onExecuteResult", + "executeTime": "13" +} +``` + + + + +#### 批量启动合约 + +向服务器发送请求, 启动服务器中保存有合约脚本的一系列合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | ------------------------------------ | +| action | startContractBatched | +| fileList | 合约脚本文件列表(Json数组,URLEncode) | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=startContractBatched&fileList=%5B%20%22EventPuber.yjs%22%2C%20%22EventSuber.yjs%22%2C%20%22LicenceManager.yjs%22%20%5D + +``` + +##### 返回结果示例 + +```json +{"EventPuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","LicenceManager.yjs":"{\"status\":\"Success\",\"result\":\"\"}","EventSuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","action":"onStartContract"} + +``` + + + + +#### 启动Zip包合约 + +向服务器发送请求, 启动服务器中包装为`zip`格式的合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| --------- | ----------------------- | +| action | startContractInTempZips | +| owner | 调用者公钥 | +| path | zip合约(路径及)文件名 | +| signature | 调用者签名 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=startContractInTempZips&owner=0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55&path=traceTest.zip&signature=650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%2C72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2 + +``` + +##### 返回结果示例 + +```json +{"data":"verify failed","action":"onStartContract"} + +``` + + + + +#### 获取合约代码 + +向服务器发送请求, 获取某个ID合约的脚本代码. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | ----------- | +| action | getCodeByID | +| contractID | 合约ID | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=getCodeByID&contractID=814046805 + +``` + +##### 返回结果示例 + +```json +{"status":true,"action":"onCodeResult","data":"@LogType(\"Arg\")\ncontract EventSuberAtCHQ{\n\t\n \texport function init(arg){\n\t\tvar result \u003d YancloudUtil.subscribe(\"EventPuberAt3966\",\"abc\",handler);\n // print(\"Handler:\"+handler);\n \t \n \t\treturn result;\n\t}\n \texport function handler(e){\n var ret \u003d \"ReceiveEvent:\";\n\t\tret+\u003d\"\\n\";\n \tprint(ret);\n \tret+\u003dYancloudUtil.executeContract(\"EventPuberAt3966\",\"notify\",\"success\");\n \tprint(ret);\n return ret;\n\t}\n}\n"} + +``` + + + + +#### 保存合约状态 + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | ------------ | +| action | dumpContract | +| contractID | 合约ID 或 合约Name= | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/SCManager?action=dumpContract&contractID=counter&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83 + +``` + +##### 返回结果示例 + +```json +{"data":"success","size":"3.76 KB","time":"0.03s"} + +``` + + + + +#### 获取合约内存文件列表 + +向服务器发送请求, 获取某子文件夹中的所有内存文件列表. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | listMemoryFiles | +| contractID | 合约Id 或 合约Name | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/SCManager?action=listMemoryFiles&contractID=-247468535&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b + +``` + +##### 返回结果示例 + +```json +{"data":["2020-09-23.18:40:38","2020-09-24.16:03:41","2020-09-24.16:58:39","2020-09-24.18:25:47","2020-09-24.18:32:37","2020-09-24.20:54:41","2020-09-24.20:57:39","2020-09-24.21:31:07","2020-09-24.21:32:09","2020-09-24.21:36:11","2020-09-28.15:29:15","2020-09-28.20:28:29","2020-09-28.20:39:46","2020-09-28.21:45:31","2020-09-28.21:49:18","2020-09-28.22:27:34","2020-09-28.22:31:09","2020-09-28.22:32:49","2020-10-07.16:51:06","2020-10-07.16:51:23","2020-10-25.21:09:10","2020-12-14.19:06:53","2021-02-02.10:28:56","2021-02-02.10:31:13"],"action":"onListMemoryFiles"} + +``` + +#### 停止合约 + +向服务器发送请求, 停止某个合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | ------------------- | +| action | killContractProcess | +| id | 合约ID | +| *requestID | 请求ID, String类型 | + +`*`表示可选参数 + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=killContractProcess&id=-1759263594 + +``` + +##### 返回结果示例 + +```json +{"status":false,"action":"onListContractProcess","data":"[\n {\n \"id\": \"-65051856\",\n \"name\": \"EventSuber\",\n \"port\": \"1631\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"814046805\",\n \"name\": \"EventSuberAtCHQ\",\n \"port\": \"1630\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"2023975189\",\n \"name\": \"LicenceService\",\n \"port\": \"1632\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"-620602333\",\n \"name\": \"shortc\",\n \"port\": \"1627\",\n \"times\": \"0 \",\n \"traffic\": \"0.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n }\n]"} + +``` + + + + +#### 停止所有合约 + +向服务器发送请求, 停止服务器上启动的所有合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | killAllContract | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=killAllContract + +``` + +##### 返回结果示例 + +```json +{"status":false,"action":"onKillAllContract","data":"Kill:7357,7541,7548,7555,7584,7585,7591,7598,7609,7612,8440,8442,8444,8521,"} + +``` + +#### 静态分析合约 + +向服务器发送请求, 静态分析合约脚本. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | -------------------- | +| action | staticVerifyContract | +| contractid | 合约ID | +| script | 请求ID, String类型 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=staticVerifyContract&contractid=943728900&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D&path=static.yjs + +``` + +##### 返回结果示例 + +```json +{"data":"{\"status\":\"Success\",\"result\":\"{\\\"main\\\":\\\"Ret:arg \\\"}\"}","action":"onExecuteResult","cid":"943728900","executeTime":54} + +``` + + + +#### 获取合约静态分析流 + +向服务器发送请求, 获取某个合约的静态分析Control Flow. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------------ | +| action | getControlFlowByFileName | +| path | 合约ID | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=getControlFlowByFileName&path=EventSuber.yjs + +``` + +##### 返回结果示例 + +```json +{"init":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","aload 4","invokedynamic dyn:getProp|getElem|getMethod:YancloudUtil (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B3","stmts":["dup","invokedynamic dyn:getMethod|getProp|getElem:subscribe (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B4","stmts":["swap","ldc XiaomiSmartHomeAtPKU","ldc onAirPurifierModeChange","aload 4","invokedynamic dyn:getProp|getElem|getMethod:handler (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B5","stmts":["invokedynamic dyn:call:\\\u003dYancloudUtil\\,subscribe (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B6","stmts":["\u003dL3\u003d","astore 5"],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B7","stmts":["\u003dL4\u003d","aload 5","areturn"],"original":" \t\treturn result;"},{"type":"Continuous","name":"B8","stmts":["\u003dL5\u003d"],"original":" \t\treturn result;"},{"type":"Continuous","name":"B9","stmts":["\u003dL6\u003d"],"original":" \t\treturn result;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B9","label":{"label":"e"}}]},"handler":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","ldc ReceiveEvent:","aload 2","invokedynamic dyn:getProp|getElem|getMethod:content (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B3","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B4","stmts":["ldc ","invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B5","stmts":["aload 2","invokedynamic dyn:getProp|getElem|getMethod:type (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B6","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B7","stmts":["\u003dL3\u003d","astore 5"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B8","stmts":["\u003dL4\u003d","aload 4","invokedynamic dyn:getMethod|getProp|getElem:print (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":" \tprint(ret);"},{"type":"Continuous","name":"B9","stmts":["getstatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime UNDEFINED Lwrp/jdk/nashorn/internal/runtime/Undefined;","aload 5","invokedynamic dyn:call:print (Ljava/lang/Object;Lwrp/jdk/nashorn/internal/runtime/Undefined;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":" \tprint(ret);"},{"type":"Continuous","name":"B10","stmts":["pop"],"original":" \tprint(ret);"},{"type":"Continuous","name":"B11","stmts":["\u003dL5\u003d","aload 5","areturn"],"original":" return ret;"},{"type":"Continuous","name":"B12","stmts":["\u003dL6\u003d"],"original":" return ret;"},{"type":"Continuous","name":"B13","stmts":["\u003dL7\u003d"],"original":" return ret;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B8","label":{"label":"e"}},{"from":"B8","to":"B9","label":{"label":"e"}},{"from":"B9","to":"B10","label":{"label":"e"}},{"from":"B10","to":"B11","label":{"label":"e"}},{"from":"B11","to":"B13","label":{"label":"e"}}]}} + +``` + +### 日志查看类 + +#### 合约日志-查询数量 + +##### 方法 + +GET + +contractName为空或是不传入时,则为查询全部合约的条数 + + +##### 参数 + +| 字段 | 值 | +| ------------ | ------------------------ | +| action | queryContractLogSize | +| contractName | 字符串,非必须,合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogSize&contractName=NanningDataSource +``` + +##### 返回结果示例 + +```json +{ + "size": 12, + "action": "onQueryContractLogSize", + "status": "success" +} + +``` + +#### 合约日志-根据日期查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | ------------------------------------- | +| action | queryContractLogByDate | +| start | long,必须,起始时间 | +| end | long,非必须,若无end,默认为当前时间 | +| contractName | 字符串,非必须,合约名称 | + + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByDate&start=1597296300272&end=1597296305747 +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getMainFrame", + "costTime": "2493", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296300272, + "key": "-8590335427581967208" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "732", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296301030, + "key": "849660532962309239" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4580", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305745, + "key": "-8003529429500512736" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4551", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305746, + "key": "7604666709899222357" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305751, + "key": "-7561786202695627022" + } + ], + "action": "onQueryRecentContractLog" +} +``` + +#### 合约日志-根据偏移量查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | --------------------------------------------- | +| action | queryContractLogByOffset | +| count | long,必须,获取日志条数 | +| offset | long,非必须,若无offset,默认返回最新count条 | +| contractName | 字符串,非必须,合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByOffset&count=5&contractName=NanningDataSource +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305842, + "key": "-2390672423847654148" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "isOwner", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305868, + "key": "6056586201629372511" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getApplyList", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305893, + "key": "3882409580676458151" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getAcceptList", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305908, + "key": "-3437513873417136535" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "analysisByIndustry", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02", + "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}", + "date": 1597296314654, + "key": "203156239086062402" + } + ], + "action": "onQueryRecentContractLog" +} +``` + +#### 合约日志-根据key查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------------- | +| action | queryContractLogByKey | +| key | long,必须,该日志对应的key | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByKey&key=203156239086062402 +``` + +##### 返回结果 + +```json +{ + "data": { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "analysisByIndustry", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02", + "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}", + "date": 1597296314654 + }, + "action": "onQueryContractLogByKey" +} +``` + +#### 合约日志-按时间段统计调用次数 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | -------------------------------------------------------- | +| action | countContractLogGroupByCategory | +| start | long,必须,起始时间 | +| end | 非必须,终止时间,默认为当前 | +| interval | long,非必须,统计间隔 | +| category | 非必须,合约名称以逗号连接,不传入时统计全部合约调用情况 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=countContractLogGroupByCategory&start=1596758400000&interval=86400000 +``` + +##### 返回结果 + +```json +{ + "start": 1596758400000, + "interval": 86400000, + "action": "onCountContractLogGroupByCategory", + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 43, + 14 + ] +} +``` + +#### 账本日志-查询数量 + +查询通过本节点去账本上记录的日志数量 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | ---------------- | +| action | queryHashSize | +| contractName | 非必须,合约名称 | + + + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashSize&contractName=NanningDataSource +``` + +##### 返回结果 + +```json +{ + "count": "2", + "action": "onQueryHashSize" +} +``` + + +#### 账本日志-根据偏移量查询 + +查询x条通过本节点去账本上记录的日志的哈希列表 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | ----------------------------------------------------------- | +| action | queryHashByOffset | +| count | 整数,必须,表示条数 | +| offset | 整数,非必须,表示偏移量,不传入offset则默认返回最新count条 | +| contractName | 字符串,非必须,表示合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashByOffset&count=1&contractName=NanningDataSource +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "hash": "3a6c60621907146b77146c1f2d48700e47520173", + "date": 1597296314658 + } + ], + "action": "onQueryHash", + "status": "success" +} +``` + +#### 账本日志-根据hash查询详情 + +根据hash来查询日志内容 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------------------- | +| action | queryDataByHash | +| hash | 字符串,可通过queryHashByOffset | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryDataByHash&count=1&contractName=NanningDataSource&hash=3a6c60621907146b77146c1f2d48700e47520173 +``` + +##### 返回结果 + +```json +{ + "from": "0x3034643139323433323966373263656431343866", + "to": "0x65786563757465436f6e74726163740000000000", + "data": "1597296314655 --> {\"extraGas\":\"0\",\"totalGas\":\"0\",\"executionGas\":\"0\",\"signature\":\"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02\",\"costTime\":\"6\",\"arg\":\" {\\\\\\\"year\\\\\\\":2018,\\\\\\\"category\\\\\\\":\\\\\\\"工业\\\\\\\",\\\\\\\"indexType\\\\\\\":\\\\\\\"营业额\\\\\\\"}\",\"contractID\":\"-1382208250\",\"action\":\"analysisByIndustry\",\"pubKey\":\"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd\"}", + "requestID": "1597296314629_6067", + "action": "onQueryDataByHash" +} +``` + +#### 账本日志-根据requestID查询Hash + +根据requestID来查询日志内容,需由开发者保证requestID的唯一性 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| --------- | ------------------------ | +| action | queryHashByRequestID | +| requestID | 字符串,在发起调用时生成 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=queryHashByRequestID&requestID=0987654321ab +``` + +#### 节点日志-查询数量 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | ---------------------------- | +| action | queryNodeLogSize | +| category | 非必须,不传入时查询全部情况 | + +其中包括:ping、startContract、saveFile等。 + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize + +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize&category=login +``` + +##### 返回结果 + +```json +{ + "size": 177, + "action": "onQueryNodeLogSize", + "status": "success" +} +``` + +#### 节点日志-按日期查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | ---------------------------- | +| action | queryNodeLogByDate | +| start | long,必须,起始日期 | +| end | long,非必须 | +| category | 非必须,不传入时查询全部情况 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1597376006441 + +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1596758400000&category=login +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "listAllAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006438, + "key": "387355870552374748" + }, + { + "action": "listUnAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006441, + "key": "4772693258708933626" + }, + { + "action": "countRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006444, + "key": "-6425375229108830572" + }, + { + "action": "loadNodeConfig", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006448, + "key": "-6602401010405792959" + }, + { + "action": "getPeerID", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006449, + "key": "-7006776427870311552" + } + ], + "action": "onQueryNodeLogByDate" +} +``` + +#### 节点日志-按偏移量查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | --------------------------------------------- | +| action | queryNodeLogByOffset | +| count | long,必须,获取日志条数 | +| offset | long,非必须,若无offset,默认返回最新count条 | +| contractName | 字符串,非必须,合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByOffset&count=5 +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "listAllAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006438, + "key": "387355870552374748" + }, + { + "action": "listUnAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006441, + "key": "4772693258708933626" + }, + { + "action": "countRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006444, + "key": "-6425375229108830572" + }, + { + "action": "loadNodeConfig", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006448, + "key": "-6602401010405792959" + }, + { + "action": "getPeerID", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006449, + "key": "-7006776427870311552" + } + ], + "action": "onQueryNodeLogByOffset" +} +``` + +#### 节点日志-按时间段统计调用次数 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | -------------------------------------------------- | +| action | countLogGroupByCategory | +| start | long,必须,起始时间 | +| end | 非必须,终止时间,默认为当前 | +| interval | long,非必须,统计间隔 | +| category | 非必须,action以逗号连接,不传入时统计全部调用情况 | + +其中,category中的action为NodePortal的接口的action集合。 +包括:ping、startContract、saveFile等。 + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000 + +http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000&category=ping,startContract +``` + +##### 返回结果 + +```json +{ + "start": 1596758400000, + "interval": 86400000, + "action": "onCountNodeLogGroupByCategory", + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 912, + 761 + ] +} +``` + + + + + +#### 输出历史记录日志 + +向服务器发送请求, 获取节点服务器上合约的TimeTravel日志. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------ | +| action | printTimeTravelLog | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=printTimeTravelLog + +``` + +##### 返回结果示例 + +```json +{"status":false,"data":"[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa_1572335939893.dyjs\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n"} + +``` + + + + + +#### 输出节点转移日志 + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------- | +| action | printTransferLog | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=printTransferLog + +``` + +##### 返回结果示例 + +```json +{"status":false,"data":""} + +``` + + + +### 模板生成类 + + + + + + + +- - - + +## 合约节点WebSocket接口 + +### 用户管理类 + +#### 获取Session + +登录前获取session以便进行签名。 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | getSessionID | + +##### 请求示例 + +``` +var req = {}; +req.action = "getSessionID"; +wssocket.send(JSON.stringify(req)); +``` + + +##### 返回结果 + +```json +{ + "action": "onSessionID", + "session": "9782323_session" +} +``` + +#### 用户登录 + +用户进行公私钥身份验证 + +##### 参数 + +| 字段 | 值 | +| ------ | ----- | +| action | login | + +##### 请求示例 + +``` +var loginParam = {}; +loginParam.pubKey = global.sm2Key.publicKey; +loginParam.signature = sm2.doSignature(global.session, + global.sm2Key.privateKey); +loginParam.action = "login"; +wssocket.send(JSON.stringify(loginParam)); +``` + +##### 返回结果 + +```json +{ + "action": "onLogin", + "data": "NodeManager,ContractProvider" +} +``` + +#### 申请角色 + +在节点管理员界面申请可以申请称为合约管理员(ContractInstanceManager)、合约使用者(ContractUser)、合约提供者(ContractProvider) + +##### 参数 + +| 字段 | 值 | +| ------ | ------------- | +| action | applyNodeRole | +|role|申请角色名称| + +##### 请求示例 + +``` +var param = {}; +param.action = "applyNodeRole"; +param.role = "ContractUser"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +``` json +{ + "action": "onApplyRole", + "data": "success" +} + +{ + "action":"onApplyRole", + "data":"already has!" +} +``` + +#### 授权角色 + +##### 参数 + +| 字段 | 值 | +| -------- | -------------------- | +| action | authNodeRole | +| isAccept | bool类型,表示否授权 | +| pubKey | 授权用户公钥 | + + +##### 请求示例 + +``` +var param = {}; +param.action = "authNodeRole"; +param.isAccept = true; +param.pubKey = "xxxxx"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onAuthNodeRole", + "data": "success" +} +``` + +#### 删除用户角色 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------- | +| action | deleteRole | +| role | 删除角色名称 | + +##### 请求示例 + +``` +var deleteInfo = {}; +deleteInfo.pubKey = global.authorizedUsers.[publicKey]; +deleteInfo.action = "deleteRole"; +deleteInfo.role="ContractUser"; +wssocket.send(JSON.stringify(deleteInfo)); +``` + +##### 返回结果 + +```json +{ + "action": "onDeleteRole", + "data": "success" +} +``` + +#### 查看授权用户列表 + +查看准入管理员当前组网中已经授权的节点管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | listAllAuthRole | + +##### 请求示例 + +``` +var param = {}; +param.action = "listAllAuthRole"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status":false, + "action":"onListAllAuthRole", + "data": + { + "kv":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab", + "value":"NodeManager,ContractProvider,ContractUser,ContractInstanceManager"}], + "time":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab", + "value":"1617178709933"}] + } +} +``` + +#### 查看申请用户列表 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | listUnAuthRole | + +##### 请求示例 + +``` +var param = {}; +param.action = "listUnAuthRole"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onListUnAuthRole", + "kv": [{ + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": "ContractProvider,ContractUser" + }], + "time": [{ + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": "1587398989914" + }] +} +``` + + +##### 参数(删除) + +| 字段 | 值 | +| ------ | ------------- | +| action | queryUserStat | + +##### 请求示例 + +``` +var param = {}; +param.action = "queryUserStat"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onQueryUserStat", + "userListCount": 3, + "applyListCount":0 +} +``` + +### 合约代码管理类 + +#### 获取公共合约文件列表 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | listProjects | + +##### 请求示例 + +``` +var request = {}; +request.action = "listProjects"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\",\"BiddingExample\",\"ContractExecutor\"]", + "executeTime":0, + "isPrivate":false +} + +``` + + +#### 获取私有合约文件列表 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------------- | +| action | listProjects | +| pubKey | 该用户的公钥 | +|isPrivate|true| + +##### 请求示例 + +```javascript +var request = {}; +request.action = "listProjects"; +request.pubKey = "global.sm2.publicKey"; +request.isPrivate=true; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true +} +``` + + +#### 获取合约实例 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------- | +| action | listContractProcess | + +##### 请求示例 + +``` +var request = {}; +request.action = "listContractProcess"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "status":false, + "action":"onListContractProcess", + "data":"[{\"id\": \"1658407837\",\"name\": \"BDCoin\",\"port\": \"1617\"}]" +} +``` + + +#### 启动合约 + +##### 参数 + +| 字段 | 值 | +| --------- | ------------- | +| action | startContract | +| owner | pubkey | +| requestID | 当前时间 | +| script | 脚本内容 | +| signature | 签名 | + +##### 请求示例 + +``` +request.action = "startContract"; +request.owner = global.sm2Key.publicKey; +request.requestID = new Date().getTime() + ""; +request.script = global.projectScript; +request.signature = sm2.doSignature("Algorithm|" + request.script + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey); +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":\"\",\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}", + "action":"onStartContract", + "cid":"-506393888", + "executeTime":2496, + "responseID":"1617206735696" +} +``` + +#### 启动可信集群合约 + +##### 参数 + +| 字段 | 值 | +| --------- | ------------------------------------ | +| action | startContractP2PTrustfully | +| owner | pubkey | +| isPrivate | 当前时间 | +| path | 脚本所在路径 | +| signature | 签名 | +| peersID | 可信执行集群中的节点peerID组成的数组 | +| | | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "startContractP2PTrustfully"; +request.peersID = ["3r729hf2ehf982","sjdfiwoehfwoi34","wnfnwoeifnwenef"]; +var project = "JsonTest"; +request.path = "/" + project + "/mainfest.json"; +request.isPrivate = false; +request.signature = sm2.doSignature("Trusted|" + request.path + "|" ++ global.sm2Key.publicKey, global.sm2Key.privateKey); //合约的签名 +request.resultcheck = $("#resultcheck")[0].value; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"{\"status\":\"Success\",\"result\":\"\"}", + "action":"onStartContractP2PTrustfully", + "cid":"-1543583350", + "executeTime":1544 +} +``` + +#### 分发合约项目 + +##### 参数 + +| 字段 | 值 | +| ------------- | ------------------ | +| action | distributeContract | +| peersID | 集群中节点peer | +| projectName | 合约名 | +| isPrivate | 是否在私有目录 | +| sponsorPeerID | 发起者ID | +| signature | 签名 | + +##### 请求示例 + +```javascript +request.action = "distributeContract"; +request.peersID = peersID; +request.projectName = global.projects[global.lastClickedProjectId]; +request.isPrivate = $("#privateDir-tab").hasClass("active"); +request.sponsorPeerID = global.peerID; +request.signature = sm2.doSignature("DistributeContract|" + request.projectName + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey); +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onDistributeContract", + "progress":"100.00%" +} +``` + +#### 终止合约 + +##### 参数 + +| 字段 | 值 | +| --------- | ------------------- | +| action | killContractProcess | +| id | 合约id | +| requestID | 请求ID | + +##### 请求示例 + +``` +request.action = "killContractProcess"; +request.id = contractid; +request.requestID = new Date().getTime() + ""; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data": "ContractHandler: exit in 3 seconds!", + "action": "onOutputStream" +} +``` + +#### 终止所有合约 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | killAllContract | + +##### 请求示例 + +``` +request.action = "killAllContract"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "status":false, + "action":"onKillAllContract", + "data":"Kill:7241,7245," +} +``` + + + +#### 静态分析合约 + +##### 参数 + +| 字段 | 值 | +| ---------- | -------------------- | +| action | staticVerifyContract | +| owner | 用户私钥 | +| isPartial | 是否是部分 | +| contractid | contractid | +| script | 脚本内容 | +| path | 合约文件名 | + + +##### 请求示例 + +```javascript +request.action = "staticVerifyContract"; +request.owner = global.sm2Key.privateKey +request.isPartial = false; +request.contractid = contractid; +request.script = global.projectScript; +request.path = global.projectName; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json + +{ + "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":{\"hello\":\"Ret:\"},\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}", + "action":"onStaticVerifyResult", + "cid":"verify", + "executeTime":83 +} +``` + + + +#### 删除合约 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------- | +| action | deleteFile | +| file | fileName | + +##### 请求示例 + +```javascript +request.action = "deleteFile"; +request.file = fileName; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onDeleteFile", + "data":"success", + "executeTime":0 +} +``` + + + +#### 私有合约传至公共目录 + +##### 参数 + +| 字段 | 值 | +| -------- | ------------ | +| action | changePublic | +| pubkey | 用户公钥 | +| fileName | fileName | + +##### 请求示例 + +```javascript +request.action = "changePublic"; +request.pubkey = pubkey; +request.fileName = fileName; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onChangePublic", + "data":"success", + "executeTime":0 +} +``` + + + +#### 上传合约 + +##### 参数 + +| 字段 | 值 | +| -------- | ----------- | +| action | UploadFile | +| isAppend | false | +|fileName|fileName| +| path | path | +|isPrivate|true/false| +| content | fileContent(base64编码) | + +##### 请求示例 + +``` +request.action = "uploadFile"; +request.isAppend = false; +request.fileName = "test1.yjs"; +request.path = "test1"; +text="Y29udHJhY3QgdGVzdDF7CglleHBvcnQgZnVuY3Rpb24gaGVsbG8oYXJnKXsgCiAgICAgICAgcmV0dXJuICJ3b3JsZCI7ICAKICAgIH0gICAKfQ==" +request.content = text; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onUploadFile", + "data":"success", + "executeTime":0 +} +``` + +#### 编译合约 + +##### 参数 + +| 字段 | 值 | +| ---------- | -------------------------- | +| action | compile | +| path | string, 待编译的项目名称 | +| privateTab | bool, 是否为私有目录的项目 | + +##### 请求示例 + +```javascript +var req = {"action":"compile","path":"Hello","privateTab":true} +``` + +##### 返回结果 + +```json +{"result":"Hello_2020-08-17-09:09:40.ypk","action":"onCompile"} +``` + +#### 锁定私有目录 + +锁定某个用户的的私有目录编辑功能 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------------- | +| action | lockEdit | +| pubKey | string, 要被锁定的公钥 | + +##### 请求示例 + +```javascript +var req = {}; +req.action = "lockEdit"; +req.pubKey = "xxxxxx"; +wssocket.send(JSON.stringify(req)); +``` +```json +{ + "action":"onLockEdit", + "status":"success", + "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1" +} +``` + + +#### 解锁私有目录 + +解锁某个用户的的私有目录编辑功能 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------------- | +| action | unLockEdit | +| pubKey | string, 要被锁定的公钥 | + +##### 请求示例 + +```javascript +var req = {}; +req.action = unlockEdit; +req.pubKey = "xxxxxx"; +wssocket.send(JSON.stringify(req)); +``` +```json +{ + "action":"onUnlockEdit", + "status":"success", + "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1" +} +``` + + +### 合约实例管理类 + +#### 查询合约进程 + +向服务器发送请求, 查询服务器上已经启动的所有合约进程. + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------- | +| action | listContractProcess | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "listContractProcess"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "action": "onListContractProcess", + "data": "[...]" +} +``` + + + +#### 调用合约 + +向服务器发送请求, 调用某个合约. + +##### 参数 + +| 字段 | 值 | +| -------------------- | --------------------------- | +| action | executeContract | +| contractID | 合约ID | +| withDynamicAnalysis | true/false 是否进行动态分析,可选 | +| operation | 调用合约的方法名 | +| arg | 调用合约的参数 | +| pubkey | 调用者公钥,可选 | +| signature | 调用者签名 ,可选 | + +`*`表示可选参数 + +```javascript +//sm2 可从sm2.js中加载获得。 +signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey); +``` + +##### 请求示例 + +```javascript +var request = {}; +request.action = "executeContract"; +request.contractID = "2073401446"; +request.operation = "main"; +request.arg = "hhhhh"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "needSeq":false, + "seq":0, + "status":"Success", + "result":"world", + "isInsnLimit":false, + "totalGas":0, + "executionGas":0, + "extraGas":0, + "size":0, + "eventRelated":false, + "responseID":"1617211077264_223", + "action":"onExecuteResult", + "executeTime":"5" +} +``` + +#### 输出历史记录日志(删除) + +向服务器发送请求, 获取节点服务器上合约的TimeTravel日志. + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------ | +| action | printTimeTravelLog | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "printTimeTravelLog"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "data": "[CMActions] dumpContract :…t/contractExamples/memoryDumps/LicenceManager\n" +} +``` + + + +#### 输出节点转移日志(删除) + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------- | +| action | printTransferLog | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "printTransferLog"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json + { + "status": false, + "data": "" +} +``` + + + +#### 合约状态迁移 + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 参数 + +| 字段 | 值 | +| ------------ | ------------ | +| action | loadMemory | +| contractName | 合约名称 | +| memoryFile | 合约文件名称 | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "loadMemory"; +request.contractName = "JsonContract"; +request.memoryFile = "2020-03-17.20/42/55"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "data":"success", + "size":"0.00 B", + "action":"onTransferTo", + "time":"0.01s" +} +``` + + + +### 日志查看类 + +#### 查看本地近n日节点日志(删除) + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------- | +| action | listLocalNodeLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "listLocalNodeLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]" +} +``` + + + +#### 查看本地近n日合约日志(删除) + +##### 参数 + +| 字段 | 值 | +| ------ | -------------------- | +| action | listLocalContractLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "listLocalContractLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]" +} +``` + + + + +### 节点配置类 + +#### 获取节点配置信息 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | loadNodeConfig | + +##### 请求示例 + +``` +var param = {}; +param.action = "loadNodeConfig"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +``` +{ + "status": true, + "action": "onLoadNodeConfig", + "data": { + "nodeName": "04BF52213343C147E631B877BCEB17B794230EE551E85F58FA429C4BA03D690778CC384C6916C63DF36CB9E35C7E274FDB4E18491DFE3D611D347856D441CACC5AF9090B515F02AFC2DFBF56461EC83B5A4CD342466360D6CF82E6E40B637430AC4A329CCBC798DAF7D526AF9E3B3600E0BEA1BFAB8C160EF90128FAF67B19E45F37664F1E4B", + "licence": "04AADCC7103CD02626D228AFFBEF53F8242ECA4DDD6F179D30B622440666715CFBB6FD1D3678A2B25812DEA9917073E79A65F7ADE517F784DC76288EFCEB37ECAA1025E6903540702F729DA1C2ECCD93F4E6FAFCE40DF443E7FD74387169D0C6D927C7BB12882D0471C8D3E6F31B0316A42FC38F6DD9978D4351B23B2AD63E2244909E98F51185D32CB99B4AE4E22D3AB4C04027BB", + "expireTime": "Wed Aug 26 09:43:08 CST 2020", + "nodes": "[\"node1\",\"node2\",\"node3\"]", + "yjsPath": "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar", + "nodeCenter": "ws://127.0.0.1:1719/SCIDE/NodeCenter" + } +} + +{ + "status":true, + "action":"onLoadNodeConfig", + "data":{ + "nodeName":"Node_180", + "peerID":"", + "masterAddress":"39.104.201.40:21031", + "licence":"04AADCC7103C", + "doipConfig":"{\\"LHSProxyAddress\\":\\"http://39.104.201.40:21042/\\",\\"ownerHandle\\":\\"86.5000.470/dou.TEST\\",\\"certPath\\":\\"keys/dou.TEST.keystore\\",\\"certPassword\\":\\"123456\\",\\"repoID\\":\\"86.5000.470/doip.vcg9Mu1gSq_bdw\\",\\"listeners\\":\\"[{\\\\\\"url\\\\\\":\\\\\\"tcp://39.104.201.40:21032\\\\\\",\\\\\\"protocolVersion\\\\\\":\\\\\\"2.1\\\\\\",\\\\\\"messageFormat\\\\\\":\\\\\\"packet\\\\\\"}]\\",\\"serviceDescription\\":\\"test local Contract Repository\\",\\"serviceName\\":\\"ContractEngine021\\"}", + "clusterConnected":"false", + "nodePubKey":"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5", + "ipPort":"", + "bdledger":"39.108.56.240:18091,39.108.56.12:1809139.104.70.160:18091 47.98.247.70:18091 47.98.248.208:18091 39.104.77.165:18091 47.98.249.131:18091", + "yjsPath":"/data/bdwaas/bdcontract/yjs.jar", + "nodeCenter":"ws://39.104.201.21040/SCIDE/NodeCenter" + } +} +``` + + +#### 修改节点配置 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | updateConfig | +| key | 要改的配置项 | +| val | 要更改的目标值 | + +其中,key的可选项包括: + +| key的示 | val示例 | 说明 | +| ------------- | ----------------------------------- | ------------------------------- | +| yjsPath | /User/xxx/cp/yjs.jar | 合约进程启动所需的jar | +| dataChain | 192.168.1.8:18090,182.173.2.3:18091 | 账本节点的ip与端口 | +| nodeCenter | ws://127.0.0.1:18002 | CenterPortal所在的ip/端口 | +| nodeName | Node_180 | 字符串类型 | +| masterAddress | 192.168.3.2:18001 | 该NodePortal节点的ip和的TCP端口 | + +其中NodePortal的TCP端口为Node的http/ws端口号+1。 + + +#### 修改节点名称 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | changeNodeName | +| data | 新的节点名称 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeNodeName"; +param.data = "NewNodeName"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeNodeName", + "data": true +} +``` + + + +#### 修改节点YJS路径 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------- | +| action | changeYJSPath | +| data | 节点服务器yjs.jar路径 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeYJSPath"; +param.data = "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeYJSPath", + "data": true +} +``` + + + +#### 修改NodeCenter + +##### 参数 + +| 字段 | 值 | +| ------ | ----------------------------------------- | +| action | changeNodeCenter | +| data | 节点服务器要连接的NodeCenterWebSocket路径 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeNodeCenter"; +param.data = "ws://127.0.0.1:1719/SCIDE/NodeCenter"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeNodeCenter", + "data": true +} +``` + + + +#### 修改账本节点 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------------- | +| action | changeBDledger | +| data | 数链节点的IP:port,用","隔开 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeBDledger"; +param.data = "39.108.56.240:18091,39.108.56.12:18091"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeBDledger", + "data": true +} +``` + + + +#### 上传节点Licence + +##### 参数 + +| 字段 | 值 | +| ------ | ----------------------- | +| action | uploadLicence | +| data | 节点服务器的Licence内容 | + +##### 请求示例 + +``` +var param = {}; +param.action = "uploadLicence"; +param.data = "04AADCC7103C"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onUploadLicence", + "data": true +} +``` + + + +#### 获取节点ID + +##### 参数 + +| 字段 | 值 | +| ------ | --------- | +| action | getNodeID | + +##### 请求示例 + +``` +var param = {}; +param.action = "getNodeID"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onGetNodeID", + "data": "0431…d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d" +} +``` + + + +#### 获取节点所在的可信执行集群 + +##### 参数 + +| 字段 | 值 | +| ---------- | ------------------------------------------------ | +| action | getNodeTrustUnits | +| data | 节点ID | +| msgHandler | 收到回复的回调函数, 可使用"建立连接"的msgHandler | +| ws | 节点所属的NodeCenter的WebSocket地址 | + +##### 请求示例 + +``` +centerportalws = createWssocket("ws://127.0.0.1:1718/NodeCenterWS",function() { +var param = {}; +param.action = "getNodeTrustUnits"; +param.data = "0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d"; +centerportalws.send(JSON.stringify(param)); +}, msgHandler); +``` + +##### 返回结果 + +```json +{ + "data": [{ + "key": "0475c7b061...65e55_4063665700873624164", + "value": "[\"04541429c11b094…40009b4f06d\"]" + }], + "action": "onGetNodeTrustUnits" +} +``` + +### 模板生成类 + +#### 获取合约模板列表 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | getTemplateList | + +##### 请求示例 + +``` javascript +req={}; +req.action = "getTemplateList"; +wssocket.send(JSON.stringify(req)); +``` + +##### 返回结果 + +``` json +{ + "data": [ + { + "formDesc": { + "dbPWD": { + "label": "密码", + "type": "input" + }, + "contractName": { + "label": "合约名称", + "type": "input" + }, + "accessPolicy": { + "label": "访问控制策略", + "type": "input", + "option": [ + { + "text": "无访问控制", + "value": "NAC" + }, + { + "text": "直接访问控制", + "value": "DAC" + }, + { + "text": "基于角色的访问控制", + "value": "RBAC" + } + ] + }, + "dbUserName": { + "label": "用户名", + "type": "input" + }, + "fieldList": { + "label": "字段名", + "type": "tag" + }, + "dbUrl": { + "label": "数据库链接", + "type": "input" + }, + "tableName": { + "label": "表名", + "type": "input" + } + }, + "apiName": "generateMySQLProject" + }, + { + "formDesc": { + "contractName": { + "label": "合约名称", + "type": "input" + }, + "accessPolicy": { + "label": "访问控制策略", + "type": "input", + "option": [ + { + "text": "无访问控制", + "value": "NAC" + }, + { + "text": "直接访问控制", + "value": "DAC" + }, + { + "text": "基于角色的访问控制", + "value": "RBAC" + } + ] + } + }, + "apiName": "generateEmptyProject" + } + ], + "action": "onTemplateList" +} +``` + +#### 空白合约模板 + +##### 参数 + +| 字段 | 值 | +| ------------ | ----------------------------- | +| action | generateEmptyProject | +| contractName | 字符串类型,合约名称 | +| isPrivate | 布尔类型,是否为私有项目 | +| accessPolicy | 若为"DAC",则实现直接访问控制 | + +##### 请求示例 + +```javascript +var req = {}; +req.contractName = "Empty22"; +req.action = "generateEmptyProject"; +req.accessPolicy = "DAC"; +//wssocket为建立好的连接 +wssocket.send(JSON.stringify(req)); +``` + +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\"]", + "executeTime":0, + "isPrivate":false +} +``` + +#### MySQL接入合约 + +##### 参数 + +| 字段 | 值 | +| ------------- | ------------------------------------------------------ | +| action | generateMySQLProject | +| contractName | 字符串类型,合约名称 | +| isPrivate | 布尔类型,是否为私有项目 | +| dbUrl | 字符串类型,数据库的URI | +| dbUserName | 字符串类型,数据库的用户名 | +| dbPWD | 字符串类型,数据库密码 | +| accessPolicy | 若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制 | +| tableName | 字符串类型,数据库的表名 | +| fieldList | 字符串列表,数据库的字段列表 | +| defaultAccept | 布尔值,表示申请时是否默认有权 | + +##### 请求示例 + +```javascript +var req = {}; +req.contractName = "MySQLFromTemplate"; +req.action = "generateMySQLProject"; +req.pubKey = global.sm2Key.publicKey; +req.isPrivate = true; +req.tableName = "data"; +req.dbUrl = "jdbc:mysql://xxx:xxx/xxx"; +req.dbUserName = "loushuai"; +req.dbPWD = "loushuai"; +req.fieldList = [{"name":"名字","code":"*"}]; +req.basicInfo={"type":"所属分类","name":"资源名称"}; +req.accessPolicy = "DAC"; +req.defaultAccept = true; +//global.wssocket为建立好的连接 +global.wssocket.send(JSON.stringify(req)); +``` + +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true +} +``` +#### CSV接入合约 + +##### 参数 + +| 字段 | 值 | +| ----------------- | ------------------------------------------------------ | +| action | generateCSVProject | +| contractName | 字符串类型,合约名称 | +| base64EncodedData | 字符串类型,通过base64编码后的CSV文件内容 | +| isPrivate | 可选字段,布尔类型,是否为私有项目 | +| accessPolicy | 若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制 | +| defaultAccept | 可选字段,布尔值,表示申请时是否默认有权 | + +##### 请求示例 + +```javascript +var req = {}; +req.contractName = "CSVFromTemplate"; +req.action = "generateCSVProject"; +req.pubKey = global.sm2Key.publicKey; +req.isPrivate = true; +req.tableName = "data"; +req.accessPolicy = "DAC"; +req.defaultAccept = true; +req.base64EncodedData = "bmFtZSwgc2NvcmUsCmphY2ssIDkwLApsdWN5LCA5MQo="; +//global.wssocket为建立好的连接 +global.wssocket.send(JSON.stringify(req)); +``` +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true +} +``` + +- - - + +## 路由节点WebSocket接口 + +### 用户管理类 + +#### 获取Session + +登录前获取session以便进行签名。 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | getSessionID | + +##### 请求示例 + +``` +var req = {}; +req.action = "getSessionID"; +wssocket.send(JSON.stringify(req)); +``` + + +##### 返回结果 + +```json +{ + "action": "onSessionID", + "session": "9782323_session" +} +``` + + +#### 用户登录 + +用户进行公私钥身份验证,需先调用"getSessionID"获取sessionID以便于签名。 + +##### 参数 + +| 字段 | 值 | +| ------ | ----- | +| action | login | + +##### 请求示例 + +``` +var loginParam = {}; +loginParam.pubKey = global.sm2Key.publicKey; +loginParam.signature = sm2.doSignature(global.session, + global.sm2Key.privateKey); +loginParam.action = "login"; +wssocket.send(JSON.stringify(loginParam)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onLogin", + "data": "CenterManager" +} +``` + + + +#### 用户获取当前角色(删除) + +用户根据登录时的公钥获取对应的角色,如果是第一次登录则此时的公钥默认称为准入管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | ------- | +| action | getRole | + +##### 请求示例 + +``` +var param = {}; +param.action = "getRole"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onGetRole", + "data": "CenterManager" +} +``` + +#### 申请角色 + +在准入管理员界面可以申请称为组网中某个节点的节点管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | --------- | +| action | applyRole | +|role|申请的角色名称| + +##### 请求示例 + +``` +var param = {}; +param.action = "applyRole"; +param.role=" +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onApplyRole", + "data": "failed" +} +``` + + +#### 添加节点 + +##### 参数 + +| 字段 | 值 | +| ---------- | ---------------- | +| action | addNode | +| nodePubKey | 要添加的节点公钥 | + +#### 请求示例 + +``` +var req = {}; +//某节点的publicKey可通过连接该节点,并通过"获取节点配置信息"接口获取 +req.nodePubKey = publicKey; +req.action = "addNode"; +wssocket.send(JSON.stringify(req)); +``` + + +#### 删除用户角色 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | delete | +| pubKey | 对应用户的公钥 | + +##### 请求示例 + +``` +var deleteInfo = {}; +deleteInfo.pubKey = user.publicKey; +deleteInfo.action = "delete"; +wssocket.send(JSON.stringify(deleteInfo)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onDelete", + "data": "success" +} +``` + +#### 查看授权用户列表 + +查看准入管理员当前组网中已经授权的节点管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | listAllUsers | + +##### 请求示例 + +``` +var param = {}; +param.action = "onListAllUsers"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onListAllUsers", + "kv": { + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": " NodeManager" + }, + "time": { + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": 1587398989914 + } +} +``` + +#### 查看申请用户列表 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------- | +| action | listApplyList | + +##### 请求示例 + +``` +var param = {}; +param.action = "onListApplyList"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onListApplyList", + "kv": { + "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7", + "value": " NodeManager" + }, + "time": { + "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7", + "value": 1587398989914 + } +} +``` + +#### 查看用户类型分布 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------- | +| action | queryUserStat | + +##### 请求示例 + +``` +var param = {}; +param.action = "onQueryUserStat"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onQueryUserStat", + "userListCount": 3, + "applyListCount":0 +} +``` + +### 节点管理类 + +#### 查看节点列表 + +查看该用户有权限查看的节点列表(仅准入管理员及合约管理者可用) + +##### 参数 + +| 字段 | 值 | +| ------ | --------- | +| action | listNodes | + +##### 请求示例 + +``` +var param = {}; +param.action = "listNodes"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "offline": [{ + "key": "0431e31...40009b4f06d", + "value": "0431e311bd708...b4f06d" + }], + "action": "onListNodes", + "online": [{ + "contracts": [], + "pubKey": "0431e311...09b4f06d", + "nodeName": "NewNodeName", + "udpID": "528822126", + "cimanager": "" + }] +} +``` + + +#### 查看可信执行集群列表 + +查看该用户有权限查看的节点列表(仅中心管理员及合约管理者可用) + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | listTrustUnits | + +##### 请求示例 + +``` +var param = {}; +param.action = "listTrustUnits"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "data": [{ + "key": "0470b2f27f4f6…1cb855f1ecec11", + "value": "[...]" + }], + "action": "onListTrustUnits" +} +``` + + +#### 建立可信执行集群 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------------- | +| action | createTrustUnit | +| data | 节点公钥组成的Json数组 | +| Msg | 集群名称 | + +##### 请求示例 + +``` +var param = {}; +param.action = "createTrustUnit"; +param.data = "[\"382r0934309t...\",\"345343rr3f34...\"]"; +param.msg = "newUnit1"; +global.wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onCreateTrustUnit", + "status": "Success" +} +``` + + +#### 删除可信执行集群 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | deleteTrustUnit | +| data | 可信执行集群ID | + +##### 请求示例 + +``` +var param = {}; +param.action = "deleteTrustUnit"; +param.data = "0475d34rf3434..._1583410158761"; +global.wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onDeleteTrustUnit", + "status": "Success" +} +``` + + + +### 日志查看类 + +#### 查看组网管理操作的统计 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | queryActionLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "onQueryActionLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ "action":"onQueryActionLog", + "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]" +} +``` + + + +#### 查看本地近n日合约日志 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------------- | +| action | listLocalContractLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "listLocalContractLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7b...\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]" +} +``` + + +- - - + +## Bash接口 + +已废弃。可使用BDWareConfigTool代替。 +通过命令行发送Socket指令, 执行调用`ContractController`类中方法, 完成以下功能. (需要在本机的`1615`端口运行`ContractManager`实例) + +![Bash接口功能示意图](./_static/imgs/bash-api.png) + +### 指令 + +```bash +java -jar yjs.jar function_name arguments + +``` + +`function_name`为调用的方法名; + +`arguments`为方法参数. + +### 启动合约 + +#### 参数 + +`function_name`为`startContract`; + +`arguments`为启动合约需要的参数, 包括合约类型`type`, 合约ID`id`, 合约脚本`script`. + +#### 指令示例 + +```bash +java -jar yjs.jar startContract "{\"type\":\"Algorigthm\",\"id\":\"656565\",\"script\":\"contract c{function main(arg){return arg/1.0+1;}}\"}" +``` + +### 调用合约 + +#### 参数 + +`function_name`为`executeContract`; + +`arguments`为调用合约需要的参数, 包括调用参数`arg`, 合约ID`contractID`. + +#### 指令示例 + +```bash +java -jar yjs.jar executeContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}" +``` + +### 停止合约 + +#### 参数 + +`function_name`为`stopContract`; + +`arguments`为调用合约需要的参数, 即合约ID`contractID`. + +#### 指令示例 + +```bash +java -jar yjs.jar stopContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}" +``` + +### 停止全部合约 + +#### 参数 + +`function_name`为`stopAllContracts`. + +#### 指令示例 + +```bash +java -jar yjs.jar stopAllContracts +``` + +### 查询全部合约 + +#### 参数 + +`function_name`为`listContracts`. + +#### 指令示例 + +```bash +java -jar yjs.jar listContracts +``` + \ No newline at end of file diff --git a/doc/_sources/markdown/IDEUsage.md.txt b/doc/_sources/markdown/IDEUsage.md.txt new file mode 100644 index 0000000..08568fe --- /dev/null +++ b/doc/_sources/markdown/IDEUsage.md.txt @@ -0,0 +1,439 @@ +# BDContract管理界面 + +- - - + +## 合约节点管理界面 + +该界面的使用地址为:[NodePortal.html](/NodePortal.html) + + +### 用户管理菜单 +用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。 + +#### 概览 +![nodeUserManager](./_static/imgs/nodeUserManager.jpg) +节点用户管理页面一共有四个模块:用户情况、用户活跃统计、授权用户管理、未授权用户管理。 + +#### 用户类型分布 +主要统计当前节点管理员所拥有的四种角色的数量:合约提供者、合约管理员、合约使用者 +![userList](./_static/imgs/userList.jpg) + +#### 用户活跃统计 +![userActive](./_static/imgs/userActive.jpg) +统计30天之内**登录**、**授权**、**申请**的次数 + +#### 当前用户信息 +![nodeInfo](./_static/imgs/nodeInfo.jpg) + * 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录节点管理员界面,可以将自己的公私钥复制到这个文本框中。 + * 将自己的公私钥复制完成之后要点击**导入公钥**,将公钥加入到节点管理员本地 + * 然后在**本地公钥**中可以看见公钥的前五位,选择自己的公钥,将在**我的权限**中展示出当前选择的公钥的角色,如果是还没有在中心管理员认证的节点则默认为**Anonymous** + * 如果不是节点管理员,想要加入某个中心管理员的网络,那么要在中心管理员所在的用户管理中用自己的公私钥导入后进行认证。 + * 如果想要行使更多关于合约的操作,则需要认证不同的角色:合约管理员、合约使用者、合约提供者,然后进行**角色认证** + +#### 授权与非授权用户列表 +![roleAuth](./_static/imgs/roleAuth.jpg) + 在节点管理员认证角色之后,节点管理员登录会在**未授权角色管理**表格中看见带有公钥的申请信息,如果同意,则点击**授权**,如果不同意点击**忽略**就可以。 + 授权之后将在**授权角色管理**表格中看见授权后的节点列表。如果节点管理员想要移除某个节点的角色,则在授权角色管理列表中**删除**即可。 + +### 合约代码管理菜单 + +![codeManageMenu](./_static/imgs/codeManageMenu.png) + + + +#### 合约文件 + +![codeManage1](./_static/imgs/codeManage1.png) + +在合约代码管理菜单中,用户可以看到公共合约以及个人私有合约。 +![codeManage1-1](./_static/imgs/codeManage1-1.png) + +对于公共合约,节点管理员可以对其中文件进行删除和上传操作,可以对合约项目进行下载和删除操作。 +![codeManage1-2](./_static/imgs/codeManage1-2.png) + +对于私有合约,合约提供者可以对其中文件进行删除和上传操作,可以对合约项目进行下载、删除和传至公共合约目录操作。 + +以下是对合约文件进行操作的示例。 + +#### 上传文件 +![codeManage6](./_static/imgs/codeManage6.png) + +#### 删除 +![codeManage5](./_static/imgs/codeManage5.png) + +#### 传至公共 +![codeManage7](./_static/imgs/codeManage7.png) + +#### 下拉框 + +![codeManage2](./_static/imgs/codeManage2.png) + +四个下拉框中,可以分别对合约状态保存模式、已启动合约实例、节点所在集群以及结果校验方式进行选择。 + + + +#### 按钮操作 + +![codeManage3](./_static/imgs/codeManage3.png) + +#### 启动 + +在文件列表中选择合约文件之后,在合约运行模式中选择“单节点执行”,点击启动按钮,会启动指定文件,并在结果显示框中显示返回结果。 + + + +#### 启动P2P集群合约 + +在文件列表中选择合约文件之后,在合约运行模式中选择该可信合约运行的合约集群,点击启动按钮,会在该集群的所有节点上启动指定文件,并在结果显示框中显示返回结果。 + + + +#### 启动全部 + +在合约运行模式中选择“单节点执行”,点击启动全部按钮,会启动合约文件列表中所有合约。 + + + +#### 停止P2P集群合约 + +在已启动合约实例的下拉框中选择一个合约实例,在合约运行模式中选择该可信合约运行的合约集群,点击停止按钮,会在该集群的所有节点上终止这个合约进程。 + + + +#### 停止 + +在已启动合约实例的下拉框中选择一个合约实例,点击停止按钮,会终止这个合约进程。 + + + +#### 停止全部 + +点击停止全部按钮,会停止该节点上运行的所有合约实例。 + + + +#### 静态分析 + +在合约文件列表中选择合约文件,并在合约实例下拉框中选择合约实例,点击静态分析按钮,会对该合约进行静态分析,并在结果显示框中显示返回结果。 + + + +#### 分发合约 + +在合约文件列表中选择合约项目,并在合约运行模式中选择一个集群,点击分发合约按钮,会将该合约项目打包为ypk分发给这个集群中的所有节点。 + + + + +#### 返回结果 + +![codeManage4](./_static/imgs/codeManage4.png) + +返回结果显示中显示一些操作的返回结果。 + + + +#### 合约权限配置 + +在启动合约之后,如果当前用户的角色可以查看已经启动合约进程,那么在选定查看合约进程时将会在右下方展示当前合约的IO权限。 +![permissionShow](./_static/imgs/permissionShow.png) + +如果选中的合约没有IO权限,则在当前权限的展示框中提示**当前合约没有IO权限** +![nullPermission](./_static/imgs/nullPermission.png) + +当前用户是合约管理员时可以对已有的合约IO权限进行修改。系统会提示修改后合约将有可能不会正常运行,如果还是确定要取消,那么点击**确定** 即可,反之点击**关闭** +![updatePermission](./_static/imgs/updatePermission.png) + +点击关闭或者打开之后,下一次查看同一个合约代码的进程将会默认显示最近一次修改之后的IO权限。 +![closePermission](./_static/imgs/closePermission.png) + +### 合约实例管理菜单 + +![nodeInstancesPage](./_static/imgs/nodeInstancesPage.png) + +合约实例管理菜单显示了该节点当前的所有合约实例, 用户可查看合约实例的状态, 并对合约实例进行执行或状态迁移的操作. + +#### 合约实例列表 + +![nodeInstancesList](./_static/imgs/nodeInstancesList.png) + +该列表显示了当前节点的所有合约实例信息, 包括合约ID, 合约名称, 合约类型合约状态, 合约进程端口, 合约调用次数, 合约流量, 及合约占用内存, 集群合约的结果校验模式. + +#### 合约实例执行 + +![chooseInstance](./_static/imgs/chooseInstance.png) + +用户可在合约实例的选择下拉框中选择合约实例, 对该合约实例进行操作. + +![intanceExecute](./_static/imgs/intanceExecute.png) + +选择合约实例后, 用户可在"方法"的下拉框中选择该合约的方法名, 在"参数"输入框中输入方法的参数, 点击"执行". + +用户还可点击"动态分析执行"进行带有动态分析结果的执行. + +若该合约为单点合约, 则合约在单点执行; 若该合约为集群合约, 则该合约在该集群的所有节点上执行. + +#### 合约实例执行结果 + +![executeResult](./_static/imgs/executeResult.png) + +合约实例的执行完成后的结果显示在"执行结果"区域中, 包括该次执行的ID, 执行成功/失败, 执行时间, 及执行结果. + +![analysisExecuteResult](./_static/imgs/analysisExecuteResult.png) + +若该合约的执行方式为"动态分析执行", 则结果框内除执行结果, 还会显示该次执行的动态分析结果. + +#### 合约状态迁移 + +![memoryDump](./_static/imgs/memoryDump.png) + +对于支持用户手动迁移的合约实例, 用户可点击"本地状态保存"对合约实例的状态进行保存, 或从合约的TimeTravel列表中选择已保存的合约实例, 将合约状态迁移到对应时刻. + + + +### 日志管理菜单 +![logMenu](./_static/imgs/logMenu.png) + +该菜单是对该节点本地节点日志以及合约日志的统计结果展示。 + +其中,节点管理员可以查看节点日志的相关数据;合约管理者及合约使用者可以查看该节点本地合约日志的相关数据。 + + + +#### 日志统计图 + +![log1](./_static/imgs/log1.png) + +#### 各类平台操作百分比 + +该图默认显示近2日各类平台操作占比的饼图,其中平台操作分为登陆类、用户类、日志类、合约类、维护类以及其他类这六类。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比会同步更新。 + + + +#### 各类合约操作百分比 + +合约操作分为启动、终止、静态分析和执行这四类,该图为近2日对各类合约操作占比的饼图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比会同步更新。 + + + + +#### 每日平台使用统计 + +该图为近2日平台操作次数统计的折线图。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日平台使用统计折线图会同步更新。 + + + + +#### 每日合约使用统计 + +该图为近2日对该节点上合约的操作次数统计的折线图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日合约使用统计折线图会同步更新。 + + + + +#### 日志详情 + + + +#### 节点日志详情 +![log2](./_static/imgs/log2.png) + +节点日志详情表是对节点日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比和每日平台使用统计会同步更新。 + + + +#### 合约日志详情 +![log3](./_static/imgs/log3.png) + +合约日志详情表是对合约日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比和每日合约使用统计会同步更新。 + + + +### 节点管理菜单 + +![nodeConfig](./_static/imgs/nodeConfig.png) + +节点管理菜单显示了该节点的配置信息及所属可信执行集群信息. + +#### 节点配置 + +![nodeConfigChange](./_static/imgs/nodeConfigChange.png) + +节点管理员可查看该节点的配置信息, 包括节点名称, 节点YJS路径, 节点的网络中心节点, 节点管理员还可对以上配置进行修改. + +若节点管理员修改了节点的网络中心, 该节点后重新想改节点连接, 整个页面刷新重载. + +#### 节点可信执行集群列表 + +![nodeUnits](./_static/imgs/nodeUnits.png) + +节点管理员可查看节点所属的可信执行集群信息, 包括集群创建者, 集群ID, 集群中节点数目, 集群中节点的信息. + +- - - + +#### 节点Licence配置 + +![nodeLicence](./_static/imgs/nodeLicence.png) + +用户可以查看该节点的Licence及过期时间, 还可申请Licence, 上传Licence, 保存节点UUID. + +## 智能合约在线编辑器 + +### 用户与账号 + +#### 创建账号 + +#### 申请授权 + + +### 创建项目 + +#### 新建文件 + +#### 上传文件 + +### 启动合约 +![contractMode](./_static/imgs/contractMode.png) + +####正常模式 +点击左侧启动按钮,以正常模式启动合约。 + +####debug模式 +点击右侧debug按钮,以debug模式启动合约。目前约定debug模式合约通过executeContract调用正常模式合约时,返回正常模式合约文档中的返回结果示例。 + +### 调用合约 + +###生成文档 +![genReadme](./_static/imgs/genReadme.png) + +启动合约后点击"生成文档"按钮,可以通过各export函数的@Description / @Param / @Result 对合约进行调用及结果返回,从而生成合约的说明文档。 + +- - - + +## 路由准入管理界面 + +### 权限申请与授权 + +### 仪表盘 +仪表盘为提供对准入节点中用户数量,合约数量,节点数量的概览。 + +### 整体视图 +![dashboard](./_static/imgs/dashboard.jpg) +一共分为四个模块,一个模块是用户、合约、节点数量的概览,然后分别是这三个数量的详细分类的数据统计情况。 + +### 节点数目 +![node](./_static/imgs/node.jpg) +当前在线和离线节点统计 + +### 用户类型分布 +![userAll](./_static/imgs/userAll.jpg) +当前准入节点所在组网中的节点管理员、准入管理员的数量和申请中节点的数量 + +### 合约调用情况 +![contract](./_static/imgs/contract.jpg) +当前准入节点所在组网中所有合约中事件、多点执行、ws调用、Http调用的折线统计图。 + +### 用户管理 +用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。 + +### 概览 +![centerManager](./_static/imgs/centerManager.jpg) +用户管理页面一共有四个模块。 + + +### 用户类型分布 +主要统计当前中心管理员所管理的网络中有多少节点管理员,多少个中心管理以及申请节点管理员的数量 +![userList](./_static/imgs/userList.jpg) + +### 30天内的申请情况统计 +![userApplyGraph](./_static/imgs/userApplyGraph.jpg) +统计30天之内申请节点管理员的数量和授权成为节点管理员的数量 + +### 当前用户信息 +![authNodeManager](./_static/imgs/authNodeManager.jpg) + * 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录中心管理员界面,可以将自己的公私钥复制到这个文本框中。 + * 将自己的公私钥复制完成之后要点击**导入公钥**,将公钥加入到中心管理员本地 + * 然后在**本地公钥**中可以看见公钥的前五位,选择自己的公钥,将在**我的权限**中展示出当前选择的公钥的角色,如果是中心管理员则拥有中心管理员的一切权限。 + * 如果不是中心管理员或者节点管理员,想要加入当前中心管理员的网络,那么可以在下面的选择框中选中节点管理员,进行**角色认证**。 + +### 授权与非授权用户列表 + 在中心管理员当前用户信息申请之后,中心管理员登录会在**未授权用户管理**表格中看见带有公钥的申请信息,如果同意,则点击**授权**,如果不同意点击**忽略**就可以,此时这个申请就无效。 +![authMan](./_static/imgs/authMan.jpg) + 授权之后将在**授权用户管理**表格中看见授权后的节点列表。如果中心管理员想要移除某个节点管理员的某项角色,则在授权用户管理列表中选择相应的角色,然后点击**删除**即可删除选中的角色。 +![authMana](./_static/imgs/authMana.jpg) + +### 节点管理 + +![centerNodePage](./_static/imgs/centerNodePage.png) + +节点管理为Manager对连接到自己的Cluster节点进行管理的页面, 仅Manager管理员及合约管理者可见. Manager管理员及合约管理者可在本页面查看节点信息, 并管理可信执行集群. + +### 概览 + +![centerNodePreview](./_static/imgs/centerNodePreview.png) + +概览中显示了该Manager节点所管理的所有节点的统计信息, 包括总节点数量, 总合约数量, 总订阅事件数量, 及可信执行集群数量, 右侧的饼图则为节点的分别处于Online/Offline的数量统计. + +### 节点列表 + +![centerNodeList](./_static/imgs/centerNodeList.png) + +节点列表显示了用户有权限查看的节点信息(Manager管理员可查看全部节点, 合约管理者可查看自己负责管理的Online节点). 包括节点的名称, 状态, 合约数目, 订阅事件数目, 用于节点间P2P通信的PeerID, 用于节点间UDP通信的UDPID, 及节点公钥. + +### 可信执行集群列表 + +![centerNodeUnits](./_static/imgs/centerNodeUnits.png) + +可信执行集群列表显示了用户有权限查看的可信执行集群信息(Manager管理员可查看全部集群, 合约管理者可查看自己创建的集群). 包括集群的创建者, 集群ID, 集群中节点数目, 以及集群中节点的信息. + +用户可点击列表表项的"删除"按钮, 将该集群删除. + +### 创建可信执行集群 + +![centerNodeUnitCreate](./_static/imgs/centerNodeUnitCreate.png) + +用户可以通过多选节点, 创建新的可信执行集群. 用户可以选择的节点为自己有权限查看的节点, 即Manager管理员从全部节点中选择, 合约管理者可从自己负责管理的Online节点中选择). 选择后点击提交, 即可看到创建成功的提示信息, 该集群将随即显示在可信执行集群列表中. 集群名称由创建者选取, 不能含有双引号, 该名称为合约管理者选择集群时的可见标识. + +### 日志管理 +日志管理主要展示准入节点的各项日志信息,一共分为六个模块。 +### 概览 +![log](./_static/imgs/log.jpg) + +### 管理操作分类统计(2日) +![operator](./_static/imgs/operator.jpg) +两日内所有管理类操作的统计饼图,管理类操作主要分为登录类、日志类、维护类、用户类。 + +### 管理操作每日统计(2日) +![everyLog](./_static/imgs/everyLog.jpg) +两日内管理类所有的操作每日操作统计 + +### 合约操作分类统计(2日) +![contractLog](./_static/imgs/contractLog.jpg) +两日内合约操作分类统计饼图,合约操作主要分为连接类和状态更新类。 + +### 合约操作每日统计(2日) +![contracteveryLog](./_static/imgs/contracteveryLog.jpg) +两日内合约操作数量折线统计图。 + +### 管理操作日志列表 +![opList](./_static/imgs/opList.jpg) +管理操作日志的详细信息列表。包括日志时间,管理操作名称,操作对应的节点公钥。默认展示范围是两天,可以自定义获取日志的天数。 + +### 合约操作日志列表 +![contractList](./_static/imgs/contractList.jpg) +合约操作日志详细信息列表。包括日志产生时间,合约操作名称,合约操作节点公钥。默认展示范围是两天,可以自定义获取日志的天数。 + +### 设置 + +设置页面是节点证书的状态展示以及配置节点证书 + +### 概览 +![set](./_static/imgs/set.jpg) + +### 证书状态 +![licence](./_static/imgs/licence.jpg) +证书状态主要包括许可到期时间和许可节点数量。 + +### 配置证书 +![plicence](./_static/imgs/plicence.jpg) +配置证书模块可以下载节点ID文件或者输入证书信息进行提交。 diff --git a/doc/_sources/markdown/InstallTips.md.txt b/doc/_sources/markdown/InstallTips.md.txt new file mode 100644 index 0000000..a5d6857 --- /dev/null +++ b/doc/_sources/markdown/InstallTips.md.txt @@ -0,0 +1,190 @@ +# BDContract安装说明 + + +- - - + +## 依赖环境的安装 +1.安装Java1.8环境。 + +例如,在Ubuntu下使用apt-get进行安装: + +```bash +apt-get install openjdk-8-jre +``` +在Centos环境下,使用yum进行安装: + +```bash +yum install java-1.8.0-openjdk +``` + +如果是离线环境,可先下载openjdk的安装包后进行离线安装。 + +Ubuntu下 +```bash +dpkg -i jdk-8uxxxxx.deb +``` + +在Centos环境下,使用yum进行离线安装: +```bash +yum localinstall jdk-8u271-linux-xxx.rpm +``` + +2.安装wget与unzip。 +例如,在Ubuntu下使用apt-get进行安装: + +```bash +apt-get install unzip +apt-get install wget +``` + +- - - + +## 网络拓扑说明 + +部署数瑞智能合约引擎最小仅需一个节点,此时可用作调试、测试,不能通过多节点模式来实现可信的计算。 +单节点部署时,可通过配置账本实现"防抵赖"的计算,但不能实现"难篡改"的计算。 + +多节点部署时可参考下图,包含三种逻辑节点,同一虚拟机可安装一至三种节点。 + +1)账本节点。即数瑞图式账本。 + +2)合约节点。运行代码逻辑,并通过内存缓存实现高响应的模块。与其他合约节点组成可信计算网络。 + +3)路由节点。各个合约节点的路由信息。一般单个路由节点可支持最高1000合约节点。可视情况部署多个路由节点,并在路由节点之间配置实现更大规模的节点组网。 + +一般地,同一虚拟机下,会部署**合约节点与账本节点**。 + +![deploytopology](_static/imgs/deploytopology.png) + +- - - + +## 智能合约节点安装 + +打开[安装包下载链接](https://public.internetapi.cn/?dir=releases/bdcontract/newest) +其中,下载`bdserver-lite.zip`或`bdserver.zip`,其中,`bdserver.zip`包含更多示例和文档。 +下载之后解压并启动。 + +```bash +unzip -d ./bdserver bdserver-lite.zip +cd bdserver +chmod +x *.sh +sh cmstart.sh +``` + +- - - + +## 路由准入节点安装 + +打开[安装包下载链接](https://public.internetapi.cn/?dir=releases/bdcontract/newest) +其中,下载`bdserver-cluster.zip`。 +下载之后解压并启动。 + +```bash +unzip -d ./bdcluster bdserver-cluster.zip +cd bdcluster +chmod +x *.sh +sh ncstart.sh +``` + +- - - + +## 文件说明 + +### 智能合约节点 + +![bdserver目录](_static/imgs/dirstructure.png) + +该目录下的文件说明: + +1.cmstart.sh 该脚本用于启动合约引擎。合约引擎默认监听8080端口,可通过修改cmstart.sh来修改合约引擎的监听端口。 + +2.BDWareProjectDir 该目录存放了本节点的所有合约项目。 + +3.WebContent 该目录存放了本节点的前端代码。 + +4.cp, 该目录存放了yjs.jar,为启动合约实例所需的jar。 + +5.bdserver.jar 对外提供http/websocket的服务器逻辑。 + +6.updateContract.sh 用于升级的脚本。 + +### 路由准入节点 + +安装脚本会自动下载安装并解压为bdcluster目录。 +该目录下的文件说明: + +1.ncstart.sh 该脚本用于启动节点准入中心。默认监听1718端口。可通过修改ncstart.sh来修改监听的端口。 + +2.WebContent 该目录存放了准入中心的前端代码。 + +3.bdcluster.jar 准入中心的后端。 + +- - - + +## 升级流程 + +### 合约节点 + +在命令行中输入: + +```bash +sh updateContract.sh +``` + +亦可通过[public.internetapi.cn](https://public.internetapi.cn/?dir=releases/bdcontract),下载最新文件,单独升级yjs.zip/bdserver-jar.zip/AgentWebContent来升级。 + +### 路由准入节点 + +```bash +sh updateCluster.sh +``` +亦可通过[public.internetapi.cn](https://public.internetapi.cn/?dir=releases/bdcontract),下载最新文件,单独升级bdserver-cluster.zip/ClusterWebContent.zip来升级。 + +- - - + +## 使用说明 + +### 通过参考界面使用 +当保留了WebContent目录的情况下,可使用浏览器进行配置。 +更多请使用见左侧文档[BDContract参考界面使用说明](./IDEUsage.html)。 + +#### BDWare OnlineIDE +打开[BDWare OnlineIDE](../OnlineIDE.html)。 + +#### BDWare NodePortal +打开[BDWare NodePortal](../NodePortal.html)。 + +如需组网,使用跨节点功能,则需安装路由准入中心。并按以下步骤进行配置。涉及两组公私钥。 +第一组公私钥为合约节点的、有NodeManager权限的公私钥。 +第二组公私钥为路由准入节点的、有CenterManager权限的公私钥。 + +1.打开NodePortal.html,复制该节点的NodeManager公私钥。 + +2.打开CenterPortal.html,点击右上角,将上述的NodeManager公私钥导入;并选择"NodeManager"进行身份认证。 + +3.在CenterPortal.html中切换CenterManager的公私钥,点左侧的"用户管理",通过NodeManager的认证请求。 + +4.使用NodeManager权限的公私钥打开NodePortal.html,点击:“节点管理”菜单,并配置加入网络。 +其中,加入网络的格式为:ws://centerportal的ip:端口+1。 +![配置示例](_static/imgs/config.png) + + +### 通过SDK使用 + +#### 基础知识 + +[Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) + +[Sm2加密的使用](https://github.com/JuneAndGreen/sm-crypto) + +#### SDK下载 + +1. Java版本的客户端下载:[BDWareJavaClient](_static/BDWareJavaClient.zip)。具体使用说明请下载后解压,查看README.md,并参考[ContractAPI](./ContractAPI.html)。 + +2.Javascript版本的客户端下载:[BDWareWebClient](_static/BDWareWebClient.zip)。具体使用说明请下载后解压,查看README.md,并参考[ContractAPI](./ContractAPI.html)。 + +3.配置工具[BDWareConfigTool](_static/BDWareConfigTool.zip)。具体说明请下载后解压,使用以下命令查看帮助: + +``` bash +java -jar java-client.jar -h +``` \ No newline at end of file diff --git a/doc/_sources/markdown/Introduction.md.txt b/doc/_sources/markdown/Introduction.md.txt new file mode 100644 index 0000000..6c8e725 --- /dev/null +++ b/doc/_sources/markdown/Introduction.md.txt @@ -0,0 +1,210 @@ +# BDContract介绍 + +- - - + +## 什么是BDContract? + + 北大数瑞是面向大数据场景的数据资源、IoT资源、云资源的管理、调度平台。BDContract是一个可信计算框架,计算逻辑以智能合约的方式表达。通过”随机“和”冗余计算“的方式实现智能合约的可信执行。BDContract在保证智能合约的可用性、可靠性的同时,着重提升执行效率和安全性。 + + +- - - + +## 特点 + +0. 支持多种执行模式,权衡可用性、可靠性、正确性和效率。 +1. 接入各种数据源。 +2. 支持合约的细粒度监测。 +3. 支持合约的状态。 +4. 访问控制。 +5. 支撑跨语言调用。 + + +- - - + +## 更新日志 + +* **v1.4.3** 2021年6月9日 + - 修复SSL Renegotiate Bug + - 实现内存不足时自动Hangup-Resume + - 实现contract meta的硬盘持久化 + +* **v1.4.1** 2021年5月26日 + - 实现了事件机制中的事件语义,支持“至少一次”、“至多一次”和“只有一次” + - 优化了合约模板 + - 增加模板配置文件 + - 优化了MockTemplate注解 + +* **v1.4.0** 2021年5月9日 + - 优化了ACTemplate + - 完善了DoRepo的配置联动 + +* **v1.3.9** 2021年4月22日 + - 修复了doipConfig在updateConfig中不支持的bug + - test-tool支持了sudo + - 优化了contract-template中的ACTemplate模板 + +* **v1.3.6** 2021年4月21日 + - 修复了docker中无法获取cpuid的问题 + +* **v1.3.6** 2021年4月16日 + - 修复了部分bug + - 修复了GRPCPool线程数量不足导致排队的bug + - 修复了requestID分配在压力测试下可能重复的bug + +* **v1.3.5** 2021年3月31日 + - 修复了部分bug + - http的合约调用部分增加了简单拥塞控制策略 + - 稳定性提升 + +* **v1.3.0** 2021年2月1日 + - 优化心跳机制 + - 修复部分Bug + - 更新SM2/SM3库 + - 更新前端签名计算方式 + +* **v1.2.0** 2020年12月11日 + - 优化了多节点执行模式 + - 优化了合约master路由的逻辑 + - 修复了部分bug + - 修复文件系统相关的漏洞 + +* **v1.1.0** 2020年9月 + - 支持https,并更新了该部分文档 + + +* **v1.0.9** 2020年8月27日 + - 完善IO相关工具类的文档 + - 优化合约模板:DAC持久化 + + +* **v1.0.7** 2020年8月13日 + - 优化合约日志、账本接口 + - 优化相关接口的文档 + - 提供合约模板的websocket接口 + - 自动编译bug修复 + +* **v1.0.5** 2020年7月25日 + - 弱化NC的中心化作用,集群点对点连接。 + - 优化bdwareclient + - TODO MemoryDurable + +* **v1.0.2** 2020年7月22日 + - 修复CentOS7下Too Many Opened Files的Bug + - 修复权限Bug + - 增加权限说明 + - 修复MySQLUtil的bug + - 升级BDLedger版本 + +* **v1.0.1** 2020年7月5日 + - 更新了NodePortal/CenterPortal的UI。 + - 修改了编译流程,在NodePortal中可查看编译结果,在OnlineIDE中可手动/启动时编译 + - 修改了合约分发逻辑,以编译后ypk作为分发的文件 + - 支持public目录下的ypk在多节点模式下执行时,合约故障自动恢复 + +* **v0.99** 2020年6月22日 + - 自定义合约方法的计费 + - 新增了GasExample、Incentives示例 + - 在客户端实现了"校验多点结果",并优化了结果返回的方式 + - 修复断线重连后无权限提示 + +* **v0.97** 2020年5月25日 + - cpu等资源的计量:gas机制 + - onlineIDE.html 支持上传多个文件 + - udp方式组网进行多点执行[无定序消息] + - bdwareclient.html,修复只包含计算逻辑的调用示例生成前缀错误 + +* **v0.95** 2020年5月19日 + - 修复了onlineIDE.html在的pathname有前缀时不能正确跳转bdwareclient的bug。 + - 修复了bdwareclient的pathname有前缀时自动提取url的bug。 + - 启用了合约的权限 + - 增加了NodePortal.html/OnlineIDE.html和bdwareclient.html中无权限时的提醒 + +* **v0.90** 2020年5月9日 + - 更改了yjs.jar/bdserver.jar的打包方式 + - 更新了install.sh/update.sh + - onlineIDE的修改后提醒 + - onlineIDE标签页自适应宽度 + - 文件接口隔离 + + +* **v0.8** 2020年4月26日 + - 完善文档界面和优化SDK提供方式 + - 数瑞Web客户端,客户端中所有的数据处理和如何对处理后的数据进行渲染均来自合约调用,实现可信Web应用。 + +* **v0.78** 2020年4月13日 + - 合约调用DAC示例 + - 支持动态修改IO权限 + - 支持合约状态自定义备份(定时)策略 + - 修复部分页面bug + - 日志展示优化 + - 优化账本日志展示 + - 启用部分权限访问控制 + + +* **v0.7** 2020年3月25日 + - 支持多种角色的访问控制 + - 更新了UI + +* **v0.6** 2020年2月14日 + - 优化了合约进程间的通讯 + - 尝试接入P2P网络 + +* **v0.5** 2019年12月10日 + - 完善了3种智能合约状态记录-回放策略 + - 支持了最简单的多点执行算法(不同步) + +* **v0.45** 2019年9月2日 + - 初步实现PBFT算法 + +* **v0.4** 2019年5月10日 + - 支持memory dump + +* **v0.35** 2019年4月26日 + - 实现合约的静态分析框架 + - 支持事件的发布-订阅 + +* **v0.3** 2019年1月8日 + - 支持账本数据的接入 + - 合约状态上链 + +* **v0.2** 2018年10月9日 + - 支持Python包的自动生成 + - 支持合约打包为ypk + - 支持文件、数据库等数据的接入 + +* **v0.1** 2018年8月6日 + - 定义了智能合约的语法 + - 基于nashorn引擎,实现了智能合约的执行 + +- - - + +## 使用开源项目说明 +BDWareContract项目站在了许多巨人的肩膀上,感谢这些开源项目。 + +本项目的智能合约后端使用了以下开源库。 + +| 名称 | Licence类型 | 说明 | +| ------ | ---------- | ---- | +| [Project Nashorn](https://openjdk.java.net/projects/nashorn/) | [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) | 使用了该项目的编译器,可以将js函数编译为java字节码 | +| [ASM OW2](https://projects.ow2.org/view/asm/) | [BSD](https://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_(original_%22BSD_License%22)) with attribution | 基于asm的TreeAPI与VisitorAPI实现合约的静态分析框架 | +| [Netty](https://netty.io/) | [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) | 使用netty作为Http/Websocket的服务端 | +| [gRPC](https://grpc.io/) | [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) | 使用gRPC与BDWareLedger通讯 | +| [RocksDB](https://github.com/facebook/rocksdb) | [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) | 后台数据库 | +| [ANTLR](https://github.com/antlr/antlr4) | [BSD](https://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_(original_%22BSD_License%22)) | 对合约脚本的词法分析与语法分析 | +| [SM2Java](https://github.com/PopezLotado/SM2Java) | [无](https://github.com/PopezLotado/SM2Java/blob/master/README.md) | 国密SM2 Java语言实现 | + + + +本项目的智能合约前端使用了以下开源库。 + +| 名称 | Licence类型 | 说明 | +| ------ | ---------- | ---- | +| [Bootstrap](https://getbootstrap.com/) | [MIT](https://github.com/twbs/bootstrap/blob/master/LICENSE) | 前端的排版、样式 | +| [jQuery](https://jquery.org/) | [MIT](https://jquery.org/license/) | 用于操作DOM的javascript库 | +| [jQueryUI](https://jqueryui.com/) | [MIT](https://jquery.org/license/) | 前端UI构件库 | +| [DataTables](https://datatables.net/) | [MIT](https://datatables.net/license/mit) | 表格样式 | +| [CodeMirror](https://codemirror.net/) | [MIT](https://codemirror.net/LICENSE) | 代码编辑框样式 | +| [eCharts](https://echarts.apache.org/zh/index.html) | [ApacheV2](https://www.apache.org/licenses/) | 统计图表 | +| [sm-crypto](https://github.com/JuneAndGreen/sm-crypto) | [MIT](https://github.com/JuneAndGreen/sm-crypto/blob/master/LICENCE_MIT) | 国密SM2 javascript语言实现 | + +本项目的文档使用[Sphinx](https://www.sphinx-doc.org/en/master/)生成,感谢[readthedocs](https://readthedocs.org/)提供文档样式。 \ No newline at end of file diff --git a/doc/_sources/markdown/YJSAPI.md.txt b/doc/_sources/markdown/YJSAPI.md.txt new file mode 100644 index 0000000..8d87c36 --- /dev/null +++ b/doc/_sources/markdown/YJSAPI.md.txt @@ -0,0 +1,1210 @@ +# YJS SDK +## YJS Build-in API + +### 内置对象 Global + + +### 内置对象 requester +该内置对象在export function里面会有值,仅当合约调用签名验证通过。 + + +### 执行合约 executeContract + +参数: + +``` bash +action:executeContract; +contractID:合约的id或名称均可; +operation:调用合约的方法名; +arg: 参数;格式为JSON字符串,有action与arg两个字段。 +``` + +可选参数: + +```bash +requestID:字符串类型,自行生成,用于查询hash +``` + +使用示例: + +```javascript + + function testExecutorContract(arg){ + var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg)); + if (ret.status == "Success"){ + return JSON.parse(ret.result); + }else return null; + } +``` +### 订阅事件主题 subscribe + +参数 + +``` bash +contractID:字符串类型 合约id或名称均可。 +event:字符串类型 +handler:方法名,该方法必须接受Event(内含字段topic和content)类型的唯一变量为参数;可以不是export方法 +``` + +使用示例: + +```javascript +export function init(arg) { + YancloudUtil.subscribe("topic", handler); + print("Handler: " + handler); +} + +function handler(e) { + print("topic: " + e.topic); + print("content: " + e.content); +} + +``` + +### 发布事件 pubEvent + +参数 + +``` bash +topic:字符串类型,发布的事件主题 +content:字符串类型,发布的事件内容 +``` +使用示例: + +```javascript +export function pub1(arg) { + YancloudUtil.pubEvent("topic", arg); + return "done"; +} +``` + +也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件 + +```javascript +event topic; +export function pub2(arg) { + topic(arg); + return "done"; +} +``` + +该写法与上面的`pub1`等价。 + +### 发布带语义事件 pubEventConstraint + +参数 + +``` bash +topic:字符串类型,发布的事件主题 +content:字符串类型,发布的事件内容 +semantics:枚举类型,作为字符串输入,事件语义 +``` + +事件语义参数 ++ AT_LEAST_ONCE:至少一次,默认语义 ++ AT_MOST_ONCE:至多一次 ++ ONLY_ONCE:只有一次 + +使用示例: + +```javascript +export function pub1(arg) { + YancloudUtil.pubEventConstraint("topic", arg, "AT_MOST_ONCE"); + return "done"; +} +``` + +也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名按声明的语义发布事件 + +```javascript +event AT_MOST_ONCE topic; +export function pub2(arg) { + topic(arg); + return "done"; +} +``` + +该写法与上面的`pub1`等价。 + +事先声明的事件无论是否声明语义,都可以用后缀s作为方法名的方式调用,发布任意语义的事件: + +```javascript +event topic; +export function pub3(arg) { + topics(arg, "AT_MOST_ONCE"); + return "done"; +} +``` + +该写法与上面的`pub1, pub2`等价。 + +*不带事件语义声明事件时,语义默认为至少一次(AT_LEAST_ONCE)。* + +### 访问资源文件 + +通过Global.Resources去加载ypk内部的资源文件。 + +#### loadAsInputStream + +参数: + + ```bash + path:字符串类型 需要加载文件的地址 + ``` + 使用示例: + + ```javascript + var file = Global.Resources.loadAsInputStream("/deleteit.txt"); + ``` + +#### loadAsScanner + +参数: + + ```bash + path:字符串类型 需要加载文件的地址 + ``` + + 使用示例: + + ```javascript + var scanner = Global.Resources.loadAsScanner("/local.txt"); + ``` + + + +## YJS Build-in Annotation + +### @Access + +设置合约的调用是否需要签名,这里分为两种,需签名和无签名。 +其中,"verified"表示需要签名。其他则表示无需签名。 + +``` +@Access("verified") +export function easy(arg){ + return "true"; +} +``` + +### @LogType + +LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。 + +其中,Arg表示日志中记录合约执行的参数;Result表示记录合约执行的返回结果;Branch表示记录合约执行分支。 + +例如 ,通过如下LogType注解来声明函数 + +``` +@LogType("Arg","Result","Branch") +export function easy(arg){ + Global.a = "a"; + Global.b = "b"; + if(arg > 0) + return Global.a; + else + return Global.b; +} +``` + +### @LogLocation + +该注解可以修饰`contract`或`function`。 +设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地,如果没有指定为“dataware”则仅存储在本地。 +例如,通过如下LogLocation设置存储位置。 + +在BaaS平台中,可以指定账本名称,BaaS平台默认账本为default,使用 +`@LogLocation("bdledger:default")`。如想保存到自定义的账本,比如,"abc"账本,就使用 +`@LogLocation("bdledger:abc")` + +``` +@LogLocation("dataware") +export function easy(arg){ + Global.a = "a"; +} +``` + + +### @Permission +该注解只能修饰`contract` +设置合约中调用的工具类的权限,包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类,需要在注解中添加对应的授权字段,默认只有YJS自带的YancloudUtil;如果没有添加则会抛出"未授权工具类"的异常。 +这6种工具类的详细说明在本小节后续中有说明。 + +``` +@Permission("Http","File") +contract HttpPermission { + export function main(args){ + var http=HttpUtil.httpGet(args); + var dir="adf/adfas/"; + var file=FileUtil.getDir(dir); + return YancloudUtil.currentTimeMillis(); + } +} +``` + +### @Description +该注解可以修饰`contract`或`function`。 +传入合约及函数的简介,可用于生成说明文档中关于exported函数的介绍。 + +``` +@Description("返回数据条目,无需参数") +export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); +} +``` + +### @Param +该注解可以修饰`function`。 +提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。 +``` +@Param({"offset":0,"count":100}) +export function get(args){ + var offset = args.offset; + var count = args.count; + ... +} +``` +### @MockTemplate +该注解可以修饰`function`。 +提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时,返回按照此格式生成的模拟数据。 + + +####支持的字段类型 +``` +@integer 整数 +@string 字符串 +@boolean 布尔值 +@date @time @datatime +@word 单词 @cword 中文单词 +@first @last 英文姓,名 +@cfirst @clast @cname 中文姓,名,全名 +@url @domin @ip @email +@region @province @city @county 地区,省,市,县 +…… +详细格式可以参考http://mockjs.com/examples.html +``` +####注意:模板的格式为{‘result’:模板} +```json +//返回一个对象包含如下字段 +@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}}) +//返回 +{"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"}" + + +//返回元素个数为1-5个之间的一个数组,数组的每个元素都是上述格式的一个对象 +{'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]} +//返回 +[ + {"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"}, + {"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"}, + {"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"} +] +``` +``` +@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}}) +export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); +} +``` +### @Result +该注解可以修饰`function`。 +提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。 +``` +@Result(666) +export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); +} +``` +## IO工具类 + +### 概览 + +|IO工具类名称|说明| +|---|---| +| [FileUtil](./YJSAPI.html#fileutil) | 文件操作相关的类 | +| [LedgerUtil](./YJSAPI.html#ledgerutil) | 账本操作相关的类 | +| [HttpUtil](./YJSAPI.html#httputil) | Http接口相关的类 | +| [DOIPUtil](./YJSAPI.html#doiputil) | DoIP相关的类 | +| [MySQLUtil](./YJSAPI.html#mysqlutil) | 连接mysql数据库 | +| [MongoDBUtil](./YJSAPI.html#mongodbutil) | MongoDB连接相关的类 | +| [RocksDBUtil](./YJSAPI.html#rocksdbutil) | RocksDB(基于本地文件的k-v数据库) | +| [BDWareTimeSeriesDBUtil](./YJSAPI.html#BDWareTimeSeriesDBUtil) | 基于本地文件的时间序列数据库 | + + +### FileUtil +可以使用@Permission("File")来引入FileUtil对象。 + +``` +@Permission("File") +contract FileSample { +... +} +``` + +该对象支持以下方法: + +#### copyTo + +可以复制文件和目录。第一个参数是source,第二个参数是destination。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | src | 类型为String | +| 2 | dest | 类型为String | + +##### 使用示例 + +```javascript +var ret = FileUtil.copyTo("./source.txt","./dest.txt"); +``` + +#### getContent + +获取文件的文本内容,当文件不存在时,返回```undefined```。 + +##### 参数 + +| 序号 | 参数 | 说明 | +| --- | --- | --- | +| 1 | path | 类型为String | + +##### 使用示例 + +```javascript +var ret = FileUtil.getContent("./source.txt"); +``` +#### getDir + +获取文件所在的文件夹名,输入参数为字符串。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 类型为String | + +##### 使用示例 +```javascript +var ret = FileUtil.getDir("./parent/src.txt"); +// ret 为 "./parent/"; +``` + +#### getFileName + +获取文件名。输入参数为字符串。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 类型为String | + +##### 使用示例 + +```javascript +var ret = FileUtil.getFileName("./parent/src.txt"); +// ret 为 "src.txt" +``` + + +#### openFileAsPrinter + +以PrintStream的形式打开文件。 +返回结果是```java.io.PrintStream```类型。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 文件名,类型为String | +| 2 | isAppend| 类型为boolean,表示是否往文件末尾添加 | + +##### 使用示例 + +```javascript +var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true); +ret.println("hello"); +ret.close(); +``` + +### LedgerUtil + +可以使用@Permission("Ledger")来引入LedgerUtil对象。 +``` +@Permission("Ledger") +contract LedgerExample{ +... +} +``` + +#### getClient + +获取一个连接客户端,一个参数,为对象类型。 +返回结果为LedgerClient类型,用于后续的查询账本等操作。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | address | 包含ip和端口两个字段 | + +##### 使用示例 + +```javascript +var address = {}; +address.ip = "127.0.0.1"; +address.port = 18091; +var ledgerClient = LedgerUtil.getClient(address); +``` + +#### queryByHash + +根据Hash查询Transaction。 +返回结果为对象,包含from、to、type和data四个字段,均为String类型。 +其中data为按utf-8编码解析字节数组,如果存证时用的不是utf8编码,可能返回乱码。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | client | 通过getClient方法获得的对象 | +| 2 | info | 对象类型,有两个字段ledger和hash,均为字符串类型 | + +##### 使用示例 + +```javascript +// ... ledgerClient = LedgerUtil.getClient(...); +var info = {}; +info.ledger = "bdcontract"; +info.hash = "4d3b75750835092a50085127702669615b602e53"; +var ret = LedgerUtil.queryByHash(ledgerClient,info); +print(ret.from); +print(ret.to); +print(ret.type); +print(ret.data); +``` + +#### sendTransaction + +存证数据。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | client | 通过getClient方法获得的对象 | +| 2 | info | 对象类型,有from\to\data三个字段,均为String类型 | + +##### 使用示例 + +```javascript +// ... ledgerClient = LedgerUtil.getClient(...); +var info = {}; +info.ledger = "bdcontract"; +info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155"; +info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155"; +info.data = "hello world"; +var ret = LedgerUtil.sendTransaction(ledgerClient,info); +//ret为存证的哈希值 +print(ret); +``` + +### HttpUtil + +可以使用@Permission("Http")来引入HttpUtil对象。 +``` +@Permission("Http") +contract HttpExample{ +... +} +``` + +#### createAPIGate + +配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | ip | 字符串类型,ip,端口默认为6161 | + +##### 使用示例 + +```javascript +var ret = HttpUtil.createAPIGate("192.168.4.4"); +ret.get("com.tencent.mm","sendMsg","msg"); +print(ret); +``` + +#### createAPIGate + +配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | ip | 字符串类型,ip| +| 2 | port | 字符串类型,端口 | + +##### 使用示例 + +```javascript +var ret = HttpUtil.createAPIGate("192.168.4.4", "6161"); +ret.get("com.tencent.mm","sendMsg","msg"); +print(ret); +``` + +#### get + +发起Http的get请求。 +返回结果为对象类型,包含response和responseCode两个字段。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | url | 字符串,表示url类型 | + +##### 使用示例 + +```javascript +var ret = HttpUtil.get("https://www.baidu.com"); +print(ret.responseCode); +print(ret.response); +``` + +#### post +发起Http的post请求。 +返回结果为对象类型,包含response和responseCode两个字段。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | args | 对象类型,有url,headers和data三个字段。其中,args.headers为对象类型。| + +##### 使用示例 + +```javascript +var req = {}; +req.url = "https://www.baidu.com"; +req.data = "hello"; +req.header = {}; +req.header.Accept = "application/json"; +req.header["Content-Type"] = "application/json"; +var ret = HttpUtil.post(req); +print(ret.resposeCode); +print(ret.response); +``` + +### DOIPUtil + +可以使用@Permission("DOIP")来引入DOIPUtil对象。 +``` +@Permission("DOIP") +contract DOIPExample{ + ... +} +``` + +#### call +调用一个DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型, 目标DO标识| +| 2 | arg1 | 字符串类型, 输入参数字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.call("86.5000.470/do.hello","inputString"); +``` +#### create +向一个Repository创建一个字符串类型DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型, 目标Repo标识| +| 2 | arg1 | 对象类型,包括doID,doBody字段| + +##### 使用示例 + +```javascript +var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}"); +var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject); +``` +#### delete +从一个Repository中删除DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| +| 2 | arg1 | 字符串类型 目标Repo标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo"); +``` +#### hello +获取目标Repository的DOIP服务信息 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标Repo标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo"); +``` +#### listOperation +获取目标DO支持的DOIP操作 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.listOperation("86.5000.470/do.hello"); +``` +#### register +向LHS注册一个DO,返回分配的标识 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 DO所在Repo标识| +| 2 | arg1 | 字符串类型 DO格式描述字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String"); +``` +#### reregister +修改LHS中DO的注册信息 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| +| 2 | arg1 | 字符串类型 DO所在Repo标识| +| 3 | arg2 | 字符串类型 DO格式描述字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String"); +``` +#### retrieve +获取一个DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.retrieve("86.5000.470/do.hello"); +``` +### test +测试DOIPUtils是否可用 +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 任意字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.test("hello"); +``` +#### update +更新目标DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | JS对象,包括doID,doBody字段| + +##### 使用示例 + +```javascript +var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}"); +var ret = DOIPUtil.update(digitalObject); +``` + + + +### SQLUtil + +可以使用@Permission("SQL")来引入SQLUtil对象。 +可支持MySQL/PostgreSQL/Oracle/GuassDB200等SQL数据库。 +需要将对应的jdbc的jar上传到项目中。 +例如,要使用mysql,可上传mysql-connector-java-8.0.24.jar + +``` +@Permission("SQL") +oracle MySQLExample{ +... +} +``` + +#### initDriver + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | driverClass | 字符串类型 | + +##### 使用示例 + +```javascript + //使用mysql + SQLUtil.initDriver("com.mysql.cj.jdbc.Driver"); + //使用postgresql + SQLUtil.initDriver("org.postgresql.Driver"); + //使用oracle + SQLUtil.initDriver("oracle.jdbc.OracleDriver"); +``` + +#### getConnection + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | URL | 字符串类型,jdbc连接 | +| 2 | usrName | 字符串类型,用户名 | +| 3 | pwd | 字符串类型,密码 | + + +##### 使用示例 + +```javascript +var url = "jdbc:mysql://xx.xx.xx:port/tableName"; +var usrName = "xxx"; +var pwd = "xxx"; +//配置好用户名和密码,url格式为ip或域名+端口,中间以”:”隔开。 +var conn = SQLUtil.getConnection(url,usrName,pwd); +//获取数据库连接 +var sql = "select * from newele.data"; +//创建查询语句 +var statement = conn.createStatement(); +var resultSet = statement.executeQuery(sql); +var waimailist = []; +//解析查询结果 +var meta = resultSet.getMetaData(); +for (;resultSet.next();){ + var line = {}; + for (var j=1;j<=meta.getColumnCount();j++){ + line[meta.getColumnName(j)] = resultSet.getString(j); + } + waimailist.push(line); +} +``` + +其中,getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此,可以查看: + +以了解如何进行Mysql数据库操作。 + + +### MongoDBUtil + +可以使用@Permission("MongoDB")来引入MongoDBUtil对象。 +``` +@Permission("MongoDB") +contract MongoDBExample{ +... +} +``` + +#### getConnection + + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | URL | 字符串类型 数据库的URL | +| 2 | port | 整数类型 端口号 | +| 3 | dbName | 字符串类型 数据库的名称 | +| 4 | usrName | 字符串类型 数据库的用户名 | +| 5 | pwd | 字符串类型 数据库的密码 | + + +##### 使用示例 + +**注意:port为整型,其他参数为String类型** + +```javascript +var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd); +//获取数据库对象 +var db = client.getDatabase("yancloud"); +var collection = db.getCollection("containers"); +var iter = collection.find().iterator(); +var ret =""; +for (;iter.hasNext();){ + ret+=iter.next().toJson(); + ret+="\n"; +} +``` + +其中,getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此,可以查看: + + +以了解该对象的更多方法和使用方式。 + +### RocksDBUtil + +使用@Permission("RocksDB")来引入RocksDBUtil对象。 + +``` +@Permission("RocksDB") +contract RocksDBSample { +... +} +``` + +#### loadDB + +通过loadDB来加载一个RocksDB数据库。 +加载后,可进行get/delete/put等操作。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 字符串类型 数据库部署的路径 | +| 2 | readOnly | 布尔类型 数据库只读 | + +##### 使用示例 + +``` +@Permission("RocksDB") +@Description("这是个使用RocksDB的参考代码") +contract RocksDBSample{ + function onCreate(){ + Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false"); + } + @Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}") + export function put(arg){ + arg = JSON.parse(arg); + Global.rocksdb.put(arg.key,arg.value); + return "success"; + } + @Description("示例参数: \"abc\"}") + export function get(arg){ + return Global.rocksdb.get(arg); + return "failed"; + } + @Description("示例参数: \"abc\"") + export function deleteKey(arg){ + return Global.rocksdb.delete(arg); + } + @Description("遍历KV库,无需参数") + export function iter(arg){ + var iter = Global.rocksdb.newIterator(); + var obj = undefined; + var ret = { + }; + for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){ + ret[obj.key]=obj.value; + } + return JSON.stringify(ret) + } +} +``` + +### BDWareTimeSeriesDBUtil + +使用示例 + +``` +@Permission("BDWareTimeSeriesDB") +contract BDWareTimeDBExample{ + function onCreate(arg){ + Global.dbutil = BDWareTimeSeriesDBUtil.getConnection(); + } + + export function put(arg){ + //第一个参数为表名,第二个参数为要放的value,时间戳自动打。 + Global.dbutil.put("defaultTable",arg); + return "success"; + } + @Param + export function getCount(arg){ + return Global.dbutil.getCount("defaultTable"); + } + @Param(1617254937373) + export function queryByStartTime(arg){ + var startDate = java.lang.Long.valueOf(arg); + //查询从开始时刻startDate到最新的数据 + var list = Global.dbutil.query("defaultTable",startDate); + var ret=[]; + print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size()); + var i=0; + for (i=0;i"+list.get(i)); + ret.push(list.get(i)); + } + return ret; + } + + @Description("示例参数: {\"offset\":1,\"len\":1}") + @Param({"offset":1,"len":1}) + export function queryByOffset(arg){ + var offsetLen = JSON.parse(arg); + //可配合getCount使用,查询第offset至offset+len条数据 + var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len); + var ret=[]; + print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size()); + var i=0; + for (i=0;i"+list.get(i)); + ret.push(list.get(i)); + } + return ret; + } +} + +``` + + +## 加解密工具类 + + +### SM2 +可以使用@Permission("SM2")来引入SM2Util对象。 + +``` +@Permission("SM2") +contract SM2Sample { +... +} +``` + +#### generateKeyPair +生成公私钥。 + +##### 参数 +无参数。 + +##### 使用示例 + +```javascript +var ret = SM2Util.generateKeyPair(); +print(ret.publicKey); +print(ret.privateKey); +return JSON.stringify(ret); +``` + +#### sign + +签名。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | content | 字符串类型 要进行签名的内容 | +| 2 | keyPair | sm2 | + + +##### 使用示例 + +``` +var keypair = SM2Util.generateKeyPair(); +var ret = SM2Util.sign("Hello",keypair); +print(ret.status); +//如果status是success +print(ret.signature); +//如果status是failed +print(ret.message); +``` + +#### verify + +验签。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | content | 字符串类型 待验签的内容 | +| 2 | signature | 字符串类型 签名 | +| 3 | publicKey | 字符串类型 公钥 | + +##### 使用示例 + +```javascript +var ret = SM2Util.verify("Hello","....签名","...公钥"); +// 验证通过时,result为true,status为success +// 失败时,result为failed,status为failed +print(ret.status); +print(ret.result); +``` + +## 多线程工具类 + +### AsyncUtil + +可以使用@Permission("Async")来引入AsyncUtil对象。 +``` +@Permission("Async") +contract AsyncExample{ + export function longTimeTask(arg){ + var a = { + }; + a.count = 100; + AsyncUtil.postFunction(taskFun,a); + } + function taskFun(arg){ + Global.progress = 0; + for (var i=0;i + +* Number + +* Math + +* Date + +* RegExp + +* Error + +* JSON + +## YJS应用框架 + +### 加载流程 +函数约定(getMainFrame) + +### 前端函数说明 +executeCurrentContract/..... +如何loadScript/loadCss.. + +### 后端函数约定 +getMainFrame \ No newline at end of file diff --git a/doc/_sources/markdown/YJSInDepth.md.txt b/doc/_sources/markdown/YJSInDepth.md.txt new file mode 100644 index 0000000..05068b5 --- /dev/null +++ b/doc/_sources/markdown/YJSInDepth.md.txt @@ -0,0 +1,281 @@ +# YJS语法 + +- - - + +## 概述 + +YJS源文件包括任意数量的**import声明**和一个**contract定义**。 + +- - - + +## import声明 + +与JavaScript(ES6)类似,YJS也支持import声明语句,在全局层面,开发者可以使用如下import声明来导入其他文件。 + +``` +import "filename"; +``` + +### 内容 + +import声明语句将包含在“filename”文件中的所有全局符号(单元)导入到当前文件,且全局范围内有效。 + +### 路径 + +**filename**通常用**/**做目录分隔符来表示文件的路径,例如,从同一目录下导入**x.yjs**文件到当前文件,可以使用**import "x.yjs"**语句;从其他目录下导入**x.yjs**使用**import "lib/x.yjs"**语句。 + +- - - + +## Contract定义 + +### 示例 + +以下是一个合约示例,用于JSON处理,此YJS源文件以合约名称命名。 + +``` +contract ScoreAdder{ + //arg = {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"} + export function main(arg){ + //JSON is a build-in object. + var point = JSON.parse(arg); + var s = 0; + print(point[0].score); + print(point.length); + for (var i=0;i + Data from contract: + + + + +``` +示例的资源文件"/html/hello.js"如下: + +```javascript +var queryDataFromContract = function(){ + //第一个参数为函数名,第二个为参数,第三个参数为回调。 + var data = executeCurrentContract("query","abc",function(argg){ + $("#resultText")[0].innerHTML = argg.result; + }); +} +``` + +参考示例: + + + + +### YJS-Python + +TODO + diff --git a/doc/_sources/markdown_BDWare/ContractAPI.md.txt b/doc/_sources/markdown_BDWare/ContractAPI.md.txt new file mode 100644 index 0000000..52d24f1 --- /dev/null +++ b/doc/_sources/markdown_BDWare/ContractAPI.md.txt @@ -0,0 +1,4131 @@ +# BDware SDK +除使用可视化的智能合约在线IDE外,用户还可使用WebSocket接口、Http接口、Bash接口来启动和运行合约. + +- - - + +## WebSocketSDK下载与安装 +合约SDK提供javascript版本与java版本的客户端。 + +java客户端的下载链接为:[java source](./_static/BDWareJavaClient.zip)和[jar](./_static/BDWareConfigTool.zip) +可参考java_source下的README.md及测试用例。 + +javascript的下载链接为:[js SDK](./_static/js/createWS.js) +内置的SM2加密库链接:[sm2 SDK](./_static/js/sm2.js) + +### 建立连接 +建立与节点服务器之间的WebSocket连接. + +#### 参数 + +| 字段 | 值 | +| ---------- | ------------------------------------------------------------ | +| url | 建立WebSocket的服务器URL. 使用`http`协议时, 前缀为`ws://`, 如`"ws://localhost:1717/SCIDE/SCExecutor"`; 使用`https`协议时, 前缀为`wss://` | +| msgHandler | 收到服务器WebSocket回复后的回调函数, 用户可自行编写, 也可参考下面提供的示例 | + +#### 请求示例 + +```javascript +var url = "ws://127.0.0.1:1717/SCIDE/SCExecutor";//与Slave节点建立连接 +//var url = "ws://127.0.0.1:1718/NodeCenterWS";//与Manager节点建立连接 +var msgHandler = function(m){ + console.log("recmsg:"); + console.log(m); +}; +var onOpenHandler=undefined; +wssocket = createWssocket(url,onOpenHandler,msgHandler); +``` + +#### 返回结果示例 + +``` +{ + receiveSeg: [Function (anonymous)], + isSending: false, + sendList: [], + monitor: [Function (anonymous)], + send: [Function (anonymous)], + sendNextSegment: [Function (anonymous)], + isOpen: [Function (anonymous)] +} +``` + + + +### ping + +`ping`服务器测试 + +#### 参数 + +| 字段 | 值 | +| ------ | ---- | +| action | ping | + +#### 请求示例 + +``` +var request = {}; +request.action = "ping"; +wssocket.send(JSON.stringify(request)); +``` + +#### 返回结果示例 + +``` +{ + "action":"pong" +} +``` + +### 登录 + +使用Websocket接口调用需要权限的接口时,不论是连接CenterPortal还是NodePortal必须先**登录**。 +登录的流程有3步: + +- 客户端向服务端建立连接,连接建立完成后发送{"action":"getSessionID"}(可在onOpenHandler中实现) +- 服务端收到请求后,会向客户端返回类似{"action":"onGetSessionID","session":"-4959947809200104526_session"}的结果 +- 客户端收到onGetSessionID后,会使用本地的公私钥对sessionID进行签名,并调用login接口 +- 服务端会返回onLogin的结果,data字段返回的是该公钥对应的角色。 + +- - - + +## 用户角色划分 + +### 合约节点的角色划分 + +在合约节点(NodePortal.html)中分为NodeManager/ContractProvider/ContractInstanceManager/ContractUser四类角色。 + +| 角色 | 说明 | +| ----------------------- | ------------------------------------------------------------ | +| NodeManager | 该节点的管理者,拥有用户管理、节点配置等权限 | +| ContractProvider | 拥有编辑合约、开发合约代码、运行调试等权限 | +| ContractInstanceManager | 拥有启、停合约实例、配置合约实例IO等权限 | +| ContractUser | 拥有查看合约实例列表、调用合约等权限 | +| Anonymous | 匿名用户,可以调用合约,可以申请成为ContractProvider/InstanceManager等角色 | + + +| 接口 | 说明 | 角色 | +| ------------------------------- | -------------------- | ----------------------------------------- | +| changeDumpPeriod | 设置备份周期 | ContractInstanceManager; | +| createLedger | 创建账本 | ContractInstanceManager; | +| dumpContract | 手动备份 | ContractInstanceManager; | +| deleteMemoryFile | 删除镜像 | ContractInstanceManager; | +| forkContract | 迁移合约 | ContractInstanceManager; | +| getDumpPeriod | 获取备份周期 | ContractInstanceManager; | +| killAllContract | 停止全部实例 | ContractInstanceManager; | +| killContractProcess | 停止某一实例 | ContractInstanceManager; | +| listMemoryFiles | 列取某一实例的镜像 | ContractInstanceManager; | +| loadMemory | 加载镜像 | ContractInstanceManager; | +| queryContractInstanceDOI | 查询合约实例信息 | ContractInstanceManager; | +| rebuildHashIndex | | ContractInstanceManager; | +| setPermission | | ContractProvider;ContractInstanceManager; | +| startContract | 启动合约 | ContractInstanceManager; | +| startContractBatched | 废弃 | ContractInstanceManager; | +| startContractByYPK | 启动合约 | ContractInstanceManager; | +| startContractInTempZips | 废弃 | ContractInstanceManager; | +| startContractP2PTrustfully | 启动合约(集群模式) | ContractInstanceManager; | +| updateContract | | ContractInstanceManager; | +| connectTo | 连接合约实例输出流 | ContractInstanceManager;ContractUser; | +| countContractLogGroupByAction | | ContractInstanceManager;ContractUser; | +| countContractLogGroupByCategory | | ContractInstanceManager;ContractUser; | +| getLastLog | 查询日志 | ContractInstanceManager;ContractUser; | +| getLog | 查询日志 | ContractInstanceManager;ContractUser; | +| getLogSize | 查询日志 | ContractInstanceManager;ContractUser; | +| listAllContractProcess | | ContractInstanceManager;ContractUser; | +| listContractProcess | 查询合约实例列表 | ContractInstanceManager;ContractUser; | +| listLeakContractProcess | | ContractInstanceManager;ContractUser; | +| queryContractLogByDate | | ContractInstanceManager;ContractUser; | +| queryContractLogByKey | | ContractInstanceManager;ContractUser; | +| queryContractLogByOffset | | ContractInstanceManager;ContractUser; | +| queryContractLogDetail | | ContractInstanceManager;ContractUser; | +| queryContractLogSize | | ContractInstanceManager;ContractUser; | +| queryNodeLogByDate | | ContractInstanceManager;ContractUser; | +| queryNodeLogByOffset | | ContractInstanceManager;ContractUser; | +| queryNodeLogSize | | ContractInstanceManager;ContractUser; | +| rebuildContractLogIndex | | ContractInstanceManager;ContractUser; | +| rebuildNodeLogIndex | | ContractInstanceManager;ContractUser; | +| changePublic | | ContractProvider; | +| createFile | 新建文件 | ContractProvider; | +| deleteFile | 删除文件 | ContractProvider; | +| distributeContract | | ContractProvider; | +| downloadContract | | ContractProvider; | +| downloadContractFromOtherHost | | ContractProvider; | +| generateAnnotationSample | | ContractProvider; | +| generateAppDataAnalysis | | ContractProvider; | +| generateAppDataSource | | ContractProvider; | +| generateBDCoinEventProject | | ContractProvider; | +| generateBDCoinProject | | ContractProvider; | +| generateBiddingExample | | ContractProvider; | +| generateCSVProject | | ContractProvider; | +| generateContractExecutor | | ContractProvider; | +| generateDAC4BDOA | | ContractProvider; | +| generateDAC4BDOA_persist | | ContractProvider; | +| generateDACSample | | ContractProvider; | +| generateEmptyProject | | ContractProvider; | +| generateEventPublisher | | ContractProvider; | +| generateEventSubscriber | | ContractProvider; | +| generateGasExample | | ContractProvider; | +| generateHello | | ContractProvider; | +| generateHttpExample | | ContractProvider; | +| generateIncentives | | ContractProvider; | +| generateJSONExample | | ContractProvider; | +| generateLedgerExample | | ContractProvider; | +| generateLedgerProject | | ContractProvider; | +| generateLicenceManager | | ContractProvider; | +| generateLoggerExample | | ContractProvider; | +| generateMySQLExample | | ContractProvider; | +| generateMySQLProject | | ContractProvider; | +| generatePostgreSQLSample | | ContractProvider; | +| generateReadme | | ContractProvider; | +| generateRenderSample | | ContractProvider; | +| generateRocksDBSample | | ContractProvider; | +| generateSM2Example | | ContractProvider; | +| generateStaticResource | | ContractProvider; | +| generateTFLinux | | ContractProvider; | +| generategenerateTFMac | | ContractProvider; | +| getProject | | ContractProvider; | +| getTemplateList | | ContractProvider; | +| importContractInstanceCodeByDOI | | ContractProvider; | +| listFile | | ContractProvider; | +| listProject | | ContractProvider; | +| listProjectPermission | | ContractProvider; | +| listProjects | | ContractProvider; | +| renameFile | | ContractProvider; | +| saveFile | | ContractProvider; | +| startContractAsDebug | | ContractProvider; | +| uploadFile | | ContractProvider; | +| compile | | ContractProvider;ContractInstanceManager; | +| evaluates | | ContractProvider;ContractInstanceManager; | +| executeContractP2PTrustfully | | ContractProvider;ContractInstanceManager; | +| getCodeByID | 查询代码 | ContractProvider;ContractInstanceManager; | +| getControlFlowByFileName | | ContractProvider;ContractInstanceManager; | +| getGasValue | | ContractProvider;ContractInstanceManager; | +| listCompiledFiles | | ContractProvider;ContractInstanceManager; | +| queryContractResourceInfo | | ContractProvider;ContractInstanceManager; | +| queryFreeResourceInfo | | ContractProvider;ContractInstanceManager; | +| staticVerifyContract | | ContractProvider;ContractInstanceManager; | +| writeDyjs | | ContractProvider;ContractInstanceManager; | +| authNodeRole | 授权角色 | NodeManager; | +| changeBDledger | 修改账本配置 | NodeManager; | +| changeIpPort | | NodeManager; | +| changeNodeCenter | 修改集群地址 | NodeManager; | +| changeNodeName | | NodeManager; | +| changeIpPort | | NodeManager; | +| changeDOIPConfig | | NodeManager; | +| changeYJSPath | | NodeManager; | +| countNodeLogGroupByCategory | | NodeManager; | +| countRole | | NodeManager; | +| deleteRole | | NodeManager; | +| downloadUUID | 废弃 | NodeManager; | +| getEncodedUUID | 废弃 | NodeManager; | +| getPeerID | | NodeManager; | +| listAllAuthRole | | NodeManager; | +| listNodeInfos | | NodeManager; | +| listUnAuthRole | | NodeManager; | +| loadConfig | | NodeManager; | +| loadNodeConfig | | NodeManager; | +| lockEdit | | NodeManager; | +| unlockEdit | | NodeManager; | +| updateConfig | | NodeManager; | +| uploadLicence | | NodeManager; | +| applyNodeRole | 申请角色 | 任意角色 | +| executeContract | 调用合约 | 任意角色 | +| getConnCount | | 任意角色 | +| getHashAbstractLocally | | 任意角色 | +| getHashLocally | | 任意角色 | +| getNodeRoleDeprecated | 查询当前角色 | 任意角色 | +| getSessionID | | 任意角色 | +| listAdapters | | 任意角色 | +| listTheContractProcess | | 任意角色 | +| login | 登录 | 任意角色 | +| longStr | | 任意角色 | +| ping | | 任意角色 | +| queryDataByHash | | 任意角色 | +| queryDataByHashLocally | | 任意角色 | +| queryHashByOffset | | 任意角色 | +| queryHashByRequestID | | 任意角色 | +| queryHashSize | | 任意角色 | +| queryLedgers | | 任意角色 | +| queryRole | | 任意角色 | +| queryTransactionByHash | | 任意角色 | +| sendTransaction | | 任意角色 | +| setLogStage | | 任意角色 | + +### 合约准入中心角色划分 + +共分为两类角色:CenterManager和NodeManager。其中,CenterManager拥有对集群设置的权限。 +NodeManager可以增加、删除节点等操作。 + +| 接口 | 说明 | 角色 | +| ----------------------------- | ------------ | -------------------------- | +| authNodeManager | | CenterManager; | +| countActionLogByCategory | | CenterManager; | +| countCMLogByCategory | | CenterManager; | +| delete | | CenterManager; | +| listAllUsers | | CenterManager; | +| listApplyList | | CenterManager; | +| listLicence | | CenterManager; | +| queryActionLog | | CenterManager; | +| queryCMLog | | CenterManager; | +| updateLicence | | CenterManager; | +| addNode | | CenterManager;NodeManager; | +| changeNCFile | | CenterManager;NodeManager; | +| changeOtherNC | | CenterManager;NodeManager; | +| createTrustUnit | 创建可信集群 | CenterManager;NodeManager; | +| deleteTrustUnit | | CenterManager;NodeManager; | +| getNCFile | | CenterManager;NodeManager; | +| getNodeTrustUnits | | CenterManager;NodeManager; | +| getOtherNC | | CenterManager;NodeManager; | +| listContractProcess | | CenterManager;NodeManager; | +| listMultiPointContractProcess | | CenterManager;NodeManager; | +| listNodes | | CenterManager;NodeManager; | +| listTrustUnits | | CenterManager;NodeManager; | +| queryUserStat | | CenterManager;NodeManager; | +| stopMultiPointContractProcess | | CenterManager;NodeManager; | +| applyRole | | NodeManager; | +| executeContract | 调用合约 | 任意角色 | +| executeContractTrustfully | | 任意角色 | +| getManagerPubkey | | 任意角色 | +| getNodeRole | | 任意角色 | +| getNodeSessionID | | 任意角色 | +| getRole | | 任意角色 | +| getSessionID | | 任意角色 | +| login | 登录 | 任意角色 | + +- - - + +## 合约节点Http接口 + +`http://xxx.xxx.xxx.xxx:1717/SCIDE/SCManager`为提供Http接口服务的服务器 URL(`xxx.xxx.xxx.xxx:1717`为BDWare SCIDE运行的IP和端口号) , 用户可通过在URL后附加字段参数, 完成以下功能. +`http://xxx.xxx.xxx.xxx:18000/SCIDE/SCManager` 为提供Http接口服务的服务器 + +URL(`xxx.xxx.xxx.xxx:1717` 为BDWare SCIDE运行的IP和端口号),用户可通过在URL后附加字段参数,完成以下功能: + + +### 用户管理类 + +#### ping + +`ping`服务器测试 + +##### 方法 + +GET + +##### 参数 + + +| 字段 | 值 | +| ------ | ---- | +| action | ping | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=ping +``` + +##### 返回结果示例 + +```json +{"data":"pong"} +``` + + +### 合约代码管理类 + + +#### 下载合约项目 + +##### 方法 + +GET + +##### 参数 + + +| 字段 | 值 | +| ----------- | ---------------- | +| action | downloadContract | +| projectName | 合约项目名 | +| isPrivate | 是否在私有目录下 | +| pubKey | 用户公钥 | +| timestamp | 时间戳 | +| sign | 签名 | + + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=downloadContract&projectName=BDCoin&isPrivate=false&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3 +8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275 +``` + +#### 上传文件 + +##### 方法 + +POST + + +##### 参数 + + +| 字段 | 值 | +| --------- | ---------------- | +| path | 文件上传路径 | +| fileName | 待上传文件名 | +| isPrivate | 是否在私有目录下 | +| order | 第几个数据包 | +| count | 数据包总数 | +| timestamp | 时间戳 | +| sign | 签名 | + + +##### 请求示例 + + +``` +http://127.0.0.1:18000/SCIDE/Upload?path=/TEST/TEST.yjs&fileName=WechatIMG15.jpeg&isPrivate=true&order=0&count=3&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05&sign=dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275 +``` + +##### 返回结果示例 + +```json +{"status":"true","data":"success"} +``` + +#### 保存合约脚本 + +向服务器发送请求, 向服务器本地保存合约脚本内容. + +##### 方法 + +GET + + +##### 参数 + +| 字段 | 值 | +| ------- | -------------- | +| action | writeDyjs | +| target | 合约脚本文件名 | +| content | 合约脚本内容 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=writeDyjs&target=testyjs.yjs&content=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "action": "onWriteDyjs", + "data": "success" +} +``` + +后续用户可启动并调用该合约. + + + + + + + +### 合约实例管理类 + +#### 查询合约进程 + +向服务器发送请求, 查询服务器上已经启动的所有合约进程. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------- | +| action | listContractProcess | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=listContractProcess +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "action": "onListContractProcess", + "data": "[\n {\n \"id\": \"-562752842\",\n \"name\": \"shortc\",\n \"port\": \"1626\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n }\n]" +} +``` + + +#### 启动合约 + +向服务器发送请求, 启动某个合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------------------- | +| action | startContract | +| script | 合约脚本内容, 需进行进行URIEncode | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=startContract&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D +``` + +##### 返回结果示例 + +```json +{ + "data": "{\"status\":\"Success\",\"result\":\"\"}", + "action": "onStartContract", + "cid": "-562752842", + "executeTime": 1187 +} +``` + + + +#### 调用合约 + +向服务器发送请求, 调用某个合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------------------- | --------------------------- | +| action | executeContract | +| contractID | 合约ID | +| withDynamicAnalysis | true/false 是否进行动态分析 | +| operation | 调用合约的方法名 | +| arg | 调用合约的参数 | +| pubkey | 可选,调用者公钥 | +| signature | 可选,签名 | + + +其中pubkey为sm2的公钥,计算方式如下: + +```javascript +//sm2 可从sm2.js中加载获得。 +signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey); +``` + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=executeContract&contractID=-620602333&operation=main&arg=hhh +``` + +##### 返回结果示例 + +```json +{ + "data": "{\"status\":\"Success\",\"result\":\"3\"}", + "action": "onExecuteResult", + "executeTime": "13" +} +``` + + + + +#### 批量启动合约 + +向服务器发送请求, 启动服务器中保存有合约脚本的一系列合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | ------------------------------------ | +| action | startContractBatched | +| fileList | 合约脚本文件列表(Json数组,URLEncode) | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=startContractBatched&fileList=%5B%20%22EventPuber.yjs%22%2C%20%22EventSuber.yjs%22%2C%20%22LicenceManager.yjs%22%20%5D + +``` + +##### 返回结果示例 + +```json +{"EventPuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","LicenceManager.yjs":"{\"status\":\"Success\",\"result\":\"\"}","EventSuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","action":"onStartContract"} + +``` + + + + +#### 启动Zip包合约 + +向服务器发送请求, 启动服务器中包装为`zip`格式的合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| --------- | ----------------------- | +| action | startContractInTempZips | +| owner | 调用者公钥 | +| path | zip合约(路径及)文件名 | +| signature | 调用者签名 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=startContractInTempZips&owner=0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55&path=traceTest.zip&signature=650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%2C72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2 + +``` + +##### 返回结果示例 + +```json +{"data":"verify failed","action":"onStartContract"} + +``` + + + + +#### 获取合约代码 + +向服务器发送请求, 获取某个ID合约的脚本代码. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | ----------- | +| action | getCodeByID | +| contractID | 合约ID | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=getCodeByID&contractID=814046805 + +``` + +##### 返回结果示例 + +```json +{"status":true,"action":"onCodeResult","data":"@LogType(\"Arg\")\ncontract EventSuberAtCHQ{\n\t\n \texport function init(arg){\n\t\tvar result \u003d YancloudUtil.subscribe(\"EventPuberAt3966\",\"abc\",handler);\n // print(\"Handler:\"+handler);\n \t \n \t\treturn result;\n\t}\n \texport function handler(e){\n var ret \u003d \"ReceiveEvent:\";\n\t\tret+\u003d\"\\n\";\n \tprint(ret);\n \tret+\u003dYancloudUtil.executeContract(\"EventPuberAt3966\",\"notify\",\"success\");\n \tprint(ret);\n return ret;\n\t}\n}\n"} + +``` + + + + +#### 保存合约状态 + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | ------------ | +| action | dumpContract | +| contractID | 合约ID 或 合约Name= | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/SCManager?action=dumpContract&contractID=counter&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83 + +``` + +##### 返回结果示例 + +```json +{"data":"success","size":"3.76 KB","time":"0.03s"} + +``` + + + + +#### 获取合约内存文件列表 + +向服务器发送请求, 获取某子文件夹中的所有内存文件列表. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | listMemoryFiles | +| contractID | 合约Id 或 合约Name | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/SCManager?action=listMemoryFiles&contractID=-247468535&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b + +``` + +##### 返回结果示例 + +```json +{"data":["2020-09-23.18:40:38","2020-09-24.16:03:41","2020-09-24.16:58:39","2020-09-24.18:25:47","2020-09-24.18:32:37","2020-09-24.20:54:41","2020-09-24.20:57:39","2020-09-24.21:31:07","2020-09-24.21:32:09","2020-09-24.21:36:11","2020-09-28.15:29:15","2020-09-28.20:28:29","2020-09-28.20:39:46","2020-09-28.21:45:31","2020-09-28.21:49:18","2020-09-28.22:27:34","2020-09-28.22:31:09","2020-09-28.22:32:49","2020-10-07.16:51:06","2020-10-07.16:51:23","2020-10-25.21:09:10","2020-12-14.19:06:53","2021-02-02.10:28:56","2021-02-02.10:31:13"],"action":"onListMemoryFiles"} + +``` + +#### 停止合约 + +向服务器发送请求, 停止某个合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | ------------------- | +| action | killContractProcess | +| id | 合约ID | +| *requestID | 请求ID, String类型 | + +`*`表示可选参数 + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=killContractProcess&id=-1759263594 + +``` + +##### 返回结果示例 + +```json +{"status":false,"action":"onListContractProcess","data":"[\n {\n \"id\": \"-65051856\",\n \"name\": \"EventSuber\",\n \"port\": \"1631\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"814046805\",\n \"name\": \"EventSuberAtCHQ\",\n \"port\": \"1630\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"2023975189\",\n \"name\": \"LicenceService\",\n \"port\": \"1632\",\n \"times\": \"0 \",\n \"traffic\": \"32.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n },\n {\n \"id\": \"-620602333\",\n \"name\": \"shortc\",\n \"port\": \"1627\",\n \"times\": \"0 \",\n \"traffic\": \"0.00 B\",\n \"storage\": \"0.00 B\",\n \"contractStatus\": \"Ready\"\n }\n]"} + +``` + + + + +#### 停止所有合约 + +向服务器发送请求, 停止服务器上启动的所有合约. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | killAllContract | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=killAllContract + +``` + +##### 返回结果示例 + +```json +{"status":false,"action":"onKillAllContract","data":"Kill:7357,7541,7548,7555,7584,7585,7591,7598,7609,7612,8440,8442,8444,8521,"} + +``` + +#### 静态分析合约 + +向服务器发送请求, 静态分析合约脚本. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ---------- | -------------------- | +| action | staticVerifyContract | +| contractid | 合约ID | +| script | 请求ID, String类型 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=staticVerifyContract&contractid=943728900&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D&path=static.yjs + +``` + +##### 返回结果示例 + +```json +{"data":"{\"status\":\"Success\",\"result\":\"{\\\"main\\\":\\\"Ret:arg \\\"}\"}","action":"onExecuteResult","cid":"943728900","executeTime":54} + +``` + + + +#### 获取合约静态分析流 + +向服务器发送请求, 获取某个合约的静态分析Control Flow. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------------ | +| action | getControlFlowByFileName | +| path | 合约ID | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=getControlFlowByFileName&path=EventSuber.yjs + +``` + +##### 返回结果示例 + +```json +{"init":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","aload 4","invokedynamic dyn:getProp|getElem|getMethod:YancloudUtil (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B3","stmts":["dup","invokedynamic dyn:getMethod|getProp|getElem:subscribe (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B4","stmts":["swap","ldc XiaomiSmartHomeAtPKU","ldc onAirPurifierModeChange","aload 4","invokedynamic dyn:getProp|getElem|getMethod:handler (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B5","stmts":["invokedynamic dyn:call:\\\u003dYancloudUtil\\,subscribe (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B6","stmts":["\u003dL3\u003d","astore 5"],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B7","stmts":["\u003dL4\u003d","aload 5","areturn"],"original":" \t\treturn result;"},{"type":"Continuous","name":"B8","stmts":["\u003dL5\u003d"],"original":" \t\treturn result;"},{"type":"Continuous","name":"B9","stmts":["\u003dL6\u003d"],"original":" \t\treturn result;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B9","label":{"label":"e"}}]},"handler":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","ldc ReceiveEvent:","aload 2","invokedynamic dyn:getProp|getElem|getMethod:content (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B3","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B4","stmts":["ldc ","invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B5","stmts":["aload 2","invokedynamic dyn:getProp|getElem|getMethod:type (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B6","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B7","stmts":["\u003dL3\u003d","astore 5"],"original":" var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B8","stmts":["\u003dL4\u003d","aload 4","invokedynamic dyn:getMethod|getProp|getElem:print (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":" \tprint(ret);"},{"type":"Continuous","name":"B9","stmts":["getstatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime UNDEFINED Lwrp/jdk/nashorn/internal/runtime/Undefined;","aload 5","invokedynamic dyn:call:print (Ljava/lang/Object;Lwrp/jdk/nashorn/internal/runtime/Undefined;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":" \tprint(ret);"},{"type":"Continuous","name":"B10","stmts":["pop"],"original":" \tprint(ret);"},{"type":"Continuous","name":"B11","stmts":["\u003dL5\u003d","aload 5","areturn"],"original":" return ret;"},{"type":"Continuous","name":"B12","stmts":["\u003dL6\u003d"],"original":" return ret;"},{"type":"Continuous","name":"B13","stmts":["\u003dL7\u003d"],"original":" return ret;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B8","label":{"label":"e"}},{"from":"B8","to":"B9","label":{"label":"e"}},{"from":"B9","to":"B10","label":{"label":"e"}},{"from":"B10","to":"B11","label":{"label":"e"}},{"from":"B11","to":"B13","label":{"label":"e"}}]}} + +``` + +### 日志查看类 + +#### 合约日志-查询数量 + +##### 方法 + +GET + +contractName为空或是不传入时,则为查询全部合约的条数 + + +##### 参数 + +| 字段 | 值 | +| ------------ | ------------------------ | +| action | queryContractLogSize | +| contractName | 字符串,非必须,合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogSize&contractName=NanningDataSource +``` + +##### 返回结果示例 + +```json +{ + "size": 12, + "action": "onQueryContractLogSize", + "status": "success" +} + +``` + +#### 合约日志-根据日期查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | ------------------------------------- | +| action | queryContractLogByDate | +| start | long,必须,起始时间 | +| end | long,非必须,若无end,默认为当前时间 | +| contractName | 字符串,非必须,合约名称 | + + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByDate&start=1597296300272&end=1597296305747 +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getMainFrame", + "costTime": "2493", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296300272, + "key": "-8590335427581967208" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "732", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296301030, + "key": "849660532962309239" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4580", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305745, + "key": "-8003529429500512736" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4551", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305746, + "key": "7604666709899222357" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305751, + "key": "-7561786202695627022" + } + ], + "action": "onQueryRecentContractLog" +} +``` + +#### 合约日志-根据偏移量查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | --------------------------------------------- | +| action | queryContractLogByOffset | +| count | long,必须,获取日志条数 | +| offset | long,非必须,若无offset,默认返回最新count条 | +| contractName | 字符串,非必须,合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByOffset&count=5&contractName=NanningDataSource +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "loadResource", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305842, + "key": "-2390672423847654148" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "isOwner", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305868, + "key": "6056586201629372511" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getApplyList", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305893, + "key": "3882409580676458151" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "getAcceptList", + "costTime": "4", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "date": 1597296305908, + "key": "-3437513873417136535" + }, + { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "analysisByIndustry", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02", + "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}", + "date": 1597296314654, + "key": "203156239086062402" + } + ], + "action": "onQueryRecentContractLog" +} +``` + +#### 合约日志-根据key查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------------- | +| action | queryContractLogByKey | +| key | long,必须,该日志对应的key | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByKey&key=203156239086062402 +``` + +##### 返回结果 + +```json +{ + "data": { + "action": "executeContract", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "contractID": "-1382208250", + "contractName": "NanningDataSource", + "function": "analysisByIndustry", + "costTime": "6", + "totalGas": "0", + "executionGas": "0", + "extraGas": "0", + "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02", + "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}", + "date": 1597296314654 + }, + "action": "onQueryContractLogByKey" +} +``` + +#### 合约日志-按时间段统计调用次数 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | -------------------------------------------------------- | +| action | countContractLogGroupByCategory | +| start | long,必须,起始时间 | +| end | 非必须,终止时间,默认为当前 | +| interval | long,非必须,统计间隔 | +| category | 非必须,合约名称以逗号连接,不传入时统计全部合约调用情况 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=countContractLogGroupByCategory&start=1596758400000&interval=86400000 +``` + +##### 返回结果 + +```json +{ + "start": 1596758400000, + "interval": 86400000, + "action": "onCountContractLogGroupByCategory", + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 43, + 14 + ] +} +``` + +#### 账本日志-查询数量 + +查询通过本节点去账本上记录的日志数量 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | ---------------- | +| action | queryHashSize | +| contractName | 非必须,合约名称 | + + + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashSize&contractName=NanningDataSource +``` + +##### 返回结果 + +```json +{ + "count": "2", + "action": "onQueryHashSize" +} +``` + + +#### 账本日志-根据偏移量查询 + +查询x条通过本节点去账本上记录的日志的哈希列表 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | ----------------------------------------------------------- | +| action | queryHashByOffset | +| count | 整数,必须,表示条数 | +| offset | 整数,非必须,表示偏移量,不传入offset则默认返回最新count条 | +| contractName | 字符串,非必须,表示合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashByOffset&count=1&contractName=NanningDataSource +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "hash": "3a6c60621907146b77146c1f2d48700e47520173", + "date": 1597296314658 + } + ], + "action": "onQueryHash", + "status": "success" +} +``` + +#### 账本日志-根据hash查询详情 + +根据hash来查询日志内容 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------------------- | +| action | queryDataByHash | +| hash | 字符串,可通过queryHashByOffset | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryDataByHash&count=1&contractName=NanningDataSource&hash=3a6c60621907146b77146c1f2d48700e47520173 +``` + +##### 返回结果 + +```json +{ + "from": "0x3034643139323433323966373263656431343866", + "to": "0x65786563757465436f6e74726163740000000000", + "data": "1597296314655 --> {\"extraGas\":\"0\",\"totalGas\":\"0\",\"executionGas\":\"0\",\"signature\":\"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02\",\"costTime\":\"6\",\"arg\":\" {\\\\\\\"year\\\\\\\":2018,\\\\\\\"category\\\\\\\":\\\\\\\"工业\\\\\\\",\\\\\\\"indexType\\\\\\\":\\\\\\\"营业额\\\\\\\"}\",\"contractID\":\"-1382208250\",\"action\":\"analysisByIndustry\",\"pubKey\":\"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd\"}", + "requestID": "1597296314629_6067", + "action": "onQueryDataByHash" +} +``` + +#### 账本日志-根据requestID查询Hash + +根据requestID来查询日志内容,需由开发者保证requestID的唯一性 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| --------- | ------------------------ | +| action | queryHashByRequestID | +| requestID | 字符串,在发起调用时生成 | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=queryHashByRequestID&requestID=0987654321ab +``` + +#### 节点日志-查询数量 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | ---------------------------- | +| action | queryNodeLogSize | +| category | 非必须,不传入时查询全部情况 | + +其中包括:ping、startContract、saveFile等。 + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize + +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize&category=login +``` + +##### 返回结果 + +```json +{ + "size": 177, + "action": "onQueryNodeLogSize", + "status": "success" +} +``` + +#### 节点日志-按日期查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | ---------------------------- | +| action | queryNodeLogByDate | +| start | long,必须,起始日期 | +| end | long,非必须 | +| category | 非必须,不传入时查询全部情况 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1597376006441 + +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1596758400000&category=login +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "listAllAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006438, + "key": "387355870552374748" + }, + { + "action": "listUnAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006441, + "key": "4772693258708933626" + }, + { + "action": "countRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006444, + "key": "-6425375229108830572" + }, + { + "action": "loadNodeConfig", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006448, + "key": "-6602401010405792959" + }, + { + "action": "getPeerID", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006449, + "key": "-7006776427870311552" + } + ], + "action": "onQueryNodeLogByDate" +} +``` + +#### 节点日志-按偏移量查询 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------------ | --------------------------------------------- | +| action | queryNodeLogByOffset | +| count | long,必须,获取日志条数 | +| offset | long,非必须,若无offset,默认返回最新count条 | +| contractName | 字符串,非必须,合约名称 | + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByOffset&count=5 +``` + +##### 返回结果 + +```json +{ + "data": [ + { + "action": "listAllAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006438, + "key": "387355870552374748" + }, + { + "action": "listUnAuthRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006441, + "key": "4772693258708933626" + }, + { + "action": "countRole", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006444, + "key": "-6425375229108830572" + }, + { + "action": "loadNodeConfig", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006448, + "key": "-6602401010405792959" + }, + { + "action": "getPeerID", + "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd", + "status": "accept", + "date": 1597376006449, + "key": "-7006776427870311552" + } + ], + "action": "onQueryNodeLogByOffset" +} +``` + +#### 节点日志-按时间段统计调用次数 + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| -------- | -------------------------------------------------- | +| action | countLogGroupByCategory | +| start | long,必须,起始时间 | +| end | 非必须,终止时间,默认为当前 | +| interval | long,非必须,统计间隔 | +| category | 非必须,action以逗号连接,不传入时统计全部调用情况 | + +其中,category中的action为NodePortal的接口的action集合。 +包括:ping、startContract、saveFile等。 + +##### 请求示例 + +``` +http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000 + +http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000&category=ping,startContract +``` + +##### 返回结果 + +```json +{ + "start": 1596758400000, + "interval": 86400000, + "action": "onCountNodeLogGroupByCategory", + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 912, + 761 + ] +} +``` + + + + + +#### 输出历史记录日志 + +向服务器发送请求, 获取节点服务器上合约的TimeTravel日志. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------ | +| action | printTimeTravelLog | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=printTimeTravelLog + +``` + +##### 返回结果示例 + +```json +{"status":false,"data":"[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa_1572335939893.dyjs\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n"} + +``` + + + + + +#### 输出节点转移日志 + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 方法 + +GET + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------- | +| action | printTransferLog | + +##### 请求示例 + +``` +http://127.0.0.1:1717/SCIDE/SCManager?action=printTransferLog + +``` + +##### 返回结果示例 + +```json +{"status":false,"data":""} + +``` + + + +### 模板生成类 + + + + +## 账本Http接口 +``` {.yaml} +type: google.api.Service +config_version: 3 + +http: + rules: + - selector: bdware.bdledger.api.Node.ClientVersion + get: /v0/node/version + - selector: bdware.bdledger.api.Ledger.CreateLedger + post: /v0/ledgers + body: "*" + - selector: bdware.bdledger.api.Ledger.GetLedgers + get: /v0/ledgers + - selector: bdware.bdledger.api.Ledger.SendTransaction + post: /v0/ledgers/{ledger}/transactions + body: "*" + - selector: bdware.bdledger.api.Query.GetBlockByHash + get: /v0/ledgers/{ledger}/block + - selector: bdware.bdledger.api.Query.GetBlocks + post: /v0/ledgers/{ledger}/blocks/query + body: "*" + - selector: bdware.bdledger.api.Query.CountBlocks + post: /v0/ledgers/{ledger}/blocks/count + body: "*" + - selector: bdware.bdledger.api.Query.GetRecentBlocks + get: /v0/ledgers/{ledger}/blocks/recent + - selector: bdware.bdledger.api.Query.GetTransactionByHash + get: /v0/ledgers/{ledger}/transaction + - selector: bdware.bdledger.api.Query.GetTransactionByBlockHashAndIndex + get: /v0/ledgers/{ledger}/block/transaction + - selector: bdware.bdledger.api.Query.GetTransactions + post: /v0/ledgers/{ledger}/transactions/query + body: "*" + - selector: bdware.bdledger.api.Query.CountTransactions + post: /v0/ledgers/{ledger}/transactions/count + body: "*" +``` + +> **Note** +> +> Request/Response data of **bytes** type should/will be encoded with +> [Base64](https://tools.ietf.org/html/rfc4648#section-4). + +> **Note** +> +> When using hash strings in URL, they need to be encoded with +> [encodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent). + +### 账本信息类 + +#### Node.ClientVersion {#_node_clientversion} + +Get BDLedger node version + + GET http://{{IP}}:{{PORT}}/v0/node/version + +##### 返回示例 + +``` {.json} +{ + "version": "dev-210119.a88bf4eb" +} +``` +#### Ledger.CreateLedger {#_ledger_createledger} + +Create a new ledger + + POST http://{{IP}}:{{PORT}}/v0/ledgers + +##### 请求示例 + +``` {.json} +{ + "name": "test" +} +``` + +##### 返回示例 + +``` {.json} +{ + "ok": true +} +``` + +#### Ledger.GetLedgers {#_ledger_getledgers} + +Get all ledgers + + GET http://{{IP}}:{{PORT}}/v0/ledgers + +##### 返回示例 + +``` {.json} +{ + "ledgers": [ + "default", + "test" + ] +} +``` + +#### Ledger.SendTransaction {#_ledger_sendtransaction} + +Send a new transaction + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions + +##### 请求示例 + +``` {.json} +{ + "transaction": { + "type": 0, + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": 52, + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } +} +``` + +##### 返回示例 + +``` {.json} +{ + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" +} +``` + +### 查询类 + +#### Query.GetBlockByHash {#_query_getblockbyhash} + +Get a block identified by its hash + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block?hash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D + +**hash** has to be encoded with +[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) + +##### 返回示例 + +``` {.json} +{ + "block": { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [ + { + "blockHash": "", + "blockTimestamp": "0", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } + ], + "transactionHashes": [ + "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" + ] + } +} +``` + +#### Query.GetBlocks {#_query_getblocks} + +Get blocks in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/query + +``` {.protobuf} +enum IncludeTransactions { + NONE = 0; // Don't include transaction data + HASH = 1; // Include transactions hashes + FULL = 2; // Include full transactions +} +``` + +Requirement: asciimath:\[\"start\_timestamp\"⇐\"end\_timestamp\"\] + +If only **end\_timestamp** is not specified, or +asciimath:\[\"end\_timestamp\"-\"start\_timestamp\"\>\"query.maxDuration\"\], +then **end\_timestamp** will be set to +asciimath:\[\"start\_timestamp\"+\"query.maxDuration\"\]. + +If only **start\_timestamp** is not specified, then **start\_timestamp** +will be set to asciimath:\[\"end\_timestamp\"-\"query.maxDuration\"\]. + +In all cases, **start\_timestamp** will never be earlier than the +genesis block's timestamp, and **end\_timestamp** will never be later +than the current timestamp when the node process the query request. + +##### 请求示例 +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000, + "include_transactions": 0 +} +``` + +##### 返回示例 + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [], + "transactionHashes": [] + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +##### 请求示例2 + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000, + "include_transactions": 1 +} +``` + +##### 返回示例2 + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [], + "transactionHashes": [ + "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" + ] + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +**Request body 3.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000, + "include_transactions": 2 +} +``` + +**Response 3.** + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [ + { + "blockHash": "", + "blockTimestamp": "0", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } + ], + "transactionHashes": [ + "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" + ] + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +#### Query.CountBlocks {#_query_countblocks} + +Count all blocks in a ledger, or blocks in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/count + +Requirement: asciimath:\[\"start\_timestamp\"⇐\"end\_timestamp\"\] + +If neither **start\_timestamp** nor **end\_timestamp** is specified, +then count all blocks in the specified ledger. + +If only **end\_timestamp** is not specified, then count all blocks with +timestamps later than **start\_timestamp**. + +If only **start\_timestamp** is not specified, then count all blocks +with timestamps earlier than **end\_timestamp**. + +In all cases, **start\_timestamp** will never be earlier than the +genesis block's timestamp, and **end\_timestamp** will never be later +than the current timestamp when the node process the query request. + +##### 请求示例 + +``` {.json} +{} +``` + +##### 返回示例 + +``` {.json} +{ + "count": "5", + "startTimestamp": "0", + "endTimestamp": "1611039957" +} +``` + +##### 请求示例2 + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000 +} +``` + +##### 返回示例2 + +``` {.json} +{ + "count": "1", + "startTimestamp": "1611038000", + "endTimestamp": "1611039000" +} +``` + +#### Query.GetRecentBlocks {#_query_getrecentblocks} + +Get recent **count** blocks (Only support IncludeTransactions=NONE for +now) + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/recent?count=2 + +##### 返回示例 + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [], + "transactionHashes": [] + }, + { + "hash": "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "3XkwkuMBearq8uavN76Te7Zdpl8=", + "8pZPR74OALIbps5XFb4dL/s0j0M=" + ], + "witnesses": [], + "timestamp": "1610968019", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "LuxttCm/pSHVMOKF0sJExk+DJXc=", + "transactions": [], + "transactionHashes": [] + } + ], + "startTimestamp": "1610968019", + "endTimestamp": "1611038043" +} +``` + +#### Query.GetTransactionByHash {#_query_gettransactionbyhash} + +Get a transaction identified by its hash + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/transaction?hash=VQBeA5Ee0Y5hqEileoQuYMHbOSE%3D + +**hash** has to be encoded with +[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) + +#### 返回示例 + +``` {.json} +{ + "transaction": { + "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "blockTimestamp": "1611038043", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } +} +``` + +#### Query.GetTransactionByBlockHashAndIndex {#_query_gettransactionbyblockhashandindex} + +Get a transaction identified by hash of the block it belongs to and its +index inside the block + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block/transaction?blockHash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D&index=0 + +**blockHash** has to be encoded with +[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) + +#### 返回示例 + +``` {.json} +{ + "transaction": { + "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "blockTimestamp": "1611038043", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } +} +``` + +#### Query.GetTransactions {#_query_gettransactions} + +Get transactions in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/query + +**start\_timestamp** and **end\_timestamp** follow the same requirements +and rules as in [???](#Query.GetBlocks). + +##### 请求示例 +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000 +} +``` + +##### 返回示例 + +``` {.json} +{ + "transactions": [ + { + "blockHash": "", + "blockTimestamp": "0", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +#### Query.CountTransactions {#_query_counttransactions} + +Count all transactions in a ledger, or transactions in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/count + +**start\_timestamp** and **end\_timestamp** follow the same requirements +and rules as in [???](#Query.CountBlocks). + +##### 请求示例 + +``` {.json} +{} +``` + +##### 返回示例 + +``` {.json} +{ + "count": "4", + "startTimestamp": "0", + "endTimestamp": "1611039957" +} +``` + +##### 请求示例2 + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000 +} +``` + +##### 返回示例2 + +``` {.json} +{ + "count": "1", + "startTimestamp": "1611038000", + "endTimestamp": "1611039000" +} +``` + + +- - - + +## 合约节点WebSocket接口 + +### 用户管理类 + +#### 获取Session + +登录前获取session以便进行签名。 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | getSessionID | + +##### 请求示例 + +``` +var req = {}; +req.action = "getSessionID"; +wssocket.send(JSON.stringify(req)); +``` + + +##### 返回结果 + +```json +{ + "action": "onSessionID", + "session": "9782323_session" +} +``` + +#### 用户登录 + +用户进行公私钥身份验证 + +##### 参数 + +| 字段 | 值 | +| ------ | ----- | +| action | login | + +##### 请求示例 + +``` +var loginParam = {}; +loginParam.pubKey = global.sm2Key.publicKey; +loginParam.signature = sm2.doSignature(global.session, + global.sm2Key.privateKey); +loginParam.action = "login"; +wssocket.send(JSON.stringify(loginParam)); +``` + +##### 返回结果 + +```json +{ + "action": "onLogin", + "data": "NodeManager,ContractProvider" +} +``` + +#### 申请角色 + +在节点管理员界面申请可以申请称为合约管理员(ContractInstanceManager)、合约使用者(ContractUser)、合约提供者(ContractProvider) + +##### 参数 + +| 字段 | 值 | +| ------ | ------------- | +| action | applyNodeRole | +|role|申请角色名称| + +##### 请求示例 + +``` +var param = {}; +param.action = "applyNodeRole"; +param.role = "ContractUser"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +``` json +{ + "action": "onApplyRole", + "data": "success" +} + +{ + "action":"onApplyRole", + "data":"already has!" +} +``` + +#### 授权角色 + +##### 参数 + +| 字段 | 值 | +| -------- | -------------------- | +| action | authNodeRole | +| isAccept | bool类型,表示否授权 | +| pubKey | 授权用户公钥 | + + +##### 请求示例 + +``` +var param = {}; +param.action = "authNodeRole"; +param.isAccept = true; +param.pubKey = "xxxxx"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onAuthNodeRole", + "data": "success" +} +``` + +#### 删除用户角色 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------- | +| action | deleteRole | +| role | 删除角色名称 | + +##### 请求示例 + +``` +var deleteInfo = {}; +deleteInfo.pubKey = global.authorizedUsers.[publicKey]; +deleteInfo.action = "deleteRole"; +deleteInfo.role="ContractUser"; +wssocket.send(JSON.stringify(deleteInfo)); +``` + +##### 返回结果 + +```json +{ + "action": "onDeleteRole", + "data": "success" +} +``` + +#### 查看授权用户列表 + +查看准入管理员当前组网中已经授权的节点管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | listAllAuthRole | + +##### 请求示例 + +``` +var param = {}; +param.action = "listAllAuthRole"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status":false, + "action":"onListAllAuthRole", + "data": + { + "kv":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab", + "value":"NodeManager,ContractProvider,ContractUser,ContractInstanceManager"}], + "time":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab", + "value":"1617178709933"}] + } +} +``` + +#### 查看申请用户列表 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | listUnAuthRole | + +##### 请求示例 + +``` +var param = {}; +param.action = "listUnAuthRole"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onListUnAuthRole", + "kv": [{ + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": "ContractProvider,ContractUser" + }], + "time": [{ + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": "1587398989914" + }] +} +``` + + +##### 参数(删除) + +| 字段 | 值 | +| ------ | ------------- | +| action | queryUserStat | + +##### 请求示例 + +``` +var param = {}; +param.action = "queryUserStat"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onQueryUserStat", + "userListCount": 3, + "applyListCount":0 +} +``` + +### 合约代码管理类 + +#### 获取公共合约文件列表 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | listProjects | + +##### 请求示例 + +``` +var request = {}; +request.action = "listProjects"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\",\"BiddingExample\",\"ContractExecutor\"]", + "executeTime":0, + "isPrivate":false +} + +``` + + +#### 获取私有合约文件列表 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------------- | +| action | listProjects | +| pubKey | 该用户的公钥 | +|isPrivate|true| + +##### 请求示例 + +```javascript +var request = {}; +request.action = "listProjects"; +request.pubKey = "global.sm2.publicKey"; +request.isPrivate=true; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true +} +``` + + +#### 获取合约实例 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------- | +| action | listContractProcess | + +##### 请求示例 + +``` +var request = {}; +request.action = "listContractProcess"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "status":false, + "action":"onListContractProcess", + "data":"[{\"id\": \"1658407837\",\"name\": \"BDCoin\",\"port\": \"1617\"}]" +} +``` + + +#### 启动合约 + +##### 参数 + +| 字段 | 值 | +| --------- | ------------- | +| action | startContract | +| owner | pubkey | +| requestID | 当前时间 | +| script | 脚本内容 | +| signature | 签名 | + +##### 请求示例 + +``` +request.action = "startContract"; +request.owner = global.sm2Key.publicKey; +request.requestID = new Date().getTime() + ""; +request.script = global.projectScript; +request.signature = sm2.doSignature("Algorithm|" + request.script + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey); +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":\"\",\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}", + "action":"onStartContract", + "cid":"-506393888", + "executeTime":2496, + "responseID":"1617206735696" +} +``` + +#### 启动可信集群合约 + +##### 参数 + +| 字段 | 值 | +| --------- | ------------------------------------ | +| action | startContractP2PTrustfully | +| owner | pubkey | +| isPrivate | 当前时间 | +| path | 脚本所在路径 | +| signature | 签名 | +| peersID | 可信执行集群中的节点peerID组成的数组 | +| | | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "startContractP2PTrustfully"; +request.peersID = ["3r729hf2ehf982","sjdfiwoehfwoi34","wnfnwoeifnwenef"]; +var project = "JsonTest"; +request.path = "/" + project + "/mainfest.json"; +request.isPrivate = false; +request.signature = sm2.doSignature("Trusted|" + request.path + "|" ++ global.sm2Key.publicKey, global.sm2Key.privateKey); //合约的签名 +request.resultcheck = $("#resultcheck")[0].value; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"{\"status\":\"Success\",\"result\":\"\"}", + "action":"onStartContractP2PTrustfully", + "cid":"-1543583350", + "executeTime":1544 +} +``` + +#### 分发合约项目 + +##### 参数 + +| 字段 | 值 | +| ------------- | ------------------ | +| action | distributeContract | +| peersID | 集群中节点peer | +| projectName | 合约名 | +| isPrivate | 是否在私有目录 | +| sponsorPeerID | 发起者ID | +| signature | 签名 | + +##### 请求示例 + +```javascript +request.action = "distributeContract"; +request.peersID = peersID; +request.projectName = global.projects[global.lastClickedProjectId]; +request.isPrivate = $("#privateDir-tab").hasClass("active"); +request.sponsorPeerID = global.peerID; +request.signature = sm2.doSignature("DistributeContract|" + request.projectName + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey); +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onDistributeContract", + "progress":"100.00%" +} +``` + +#### 终止合约 + +##### 参数 + +| 字段 | 值 | +| --------- | ------------------- | +| action | killContractProcess | +| id | 合约id | +| requestID | 请求ID | + +##### 请求示例 + +``` +request.action = "killContractProcess"; +request.id = contractid; +request.requestID = new Date().getTime() + ""; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data": "ContractHandler: exit in 3 seconds!", + "action": "onOutputStream" +} +``` + +#### 终止所有合约 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | killAllContract | + +##### 请求示例 + +``` +request.action = "killAllContract"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "status":false, + "action":"onKillAllContract", + "data":"Kill:7241,7245," +} +``` + + + +#### 静态分析合约 + +##### 参数 + +| 字段 | 值 | +| ---------- | -------------------- | +| action | staticVerifyContract | +| owner | 用户私钥 | +| isPartial | 是否是部分 | +| contractid | contractid | +| script | 脚本内容 | +| path | 合约文件名 | + + +##### 请求示例 + +```javascript +request.action = "staticVerifyContract"; +request.owner = global.sm2Key.privateKey +request.isPartial = false; +request.contractid = contractid; +request.script = global.projectScript; +request.path = global.projectName; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json + +{ + "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":{\"hello\":\"Ret:\"},\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}", + "action":"onStaticVerifyResult", + "cid":"verify", + "executeTime":83 +} +``` + + + +#### 删除合约 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------- | +| action | deleteFile | +| file | fileName | + +##### 请求示例 + +```javascript +request.action = "deleteFile"; +request.file = fileName; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onDeleteFile", + "data":"success", + "executeTime":0 +} +``` + + + +#### 私有合约传至公共目录 + +##### 参数 + +| 字段 | 值 | +| -------- | ------------ | +| action | changePublic | +| pubkey | 用户公钥 | +| fileName | fileName | + +##### 请求示例 + +```javascript +request.action = "changePublic"; +request.pubkey = pubkey; +request.fileName = fileName; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onChangePublic", + "data":"success", + "executeTime":0 +} +``` + + + +#### 上传合约 + +##### 参数 + +| 字段 | 值 | +| -------- | ----------- | +| action | UploadFile | +| isAppend | false | +|fileName|fileName| +| path | path | +|isPrivate|true/false| +| content | fileContent(base64编码) | + +##### 请求示例 + +``` +request.action = "uploadFile"; +request.isAppend = false; +request.fileName = "test1.yjs"; +request.path = "test1"; +text="Y29udHJhY3QgdGVzdDF7CglleHBvcnQgZnVuY3Rpb24gaGVsbG8oYXJnKXsgCiAgICAgICAgcmV0dXJuICJ3b3JsZCI7ICAKICAgIH0gICAKfQ==" +request.content = text; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "action":"onUploadFile", + "data":"success", + "executeTime":0 +} +``` + +#### 编译合约 + +##### 参数 + +| 字段 | 值 | +| ---------- | -------------------------- | +| action | compile | +| path | string, 待编译的项目名称 | +| privateTab | bool, 是否为私有目录的项目 | + +##### 请求示例 + +```javascript +var req = {"action":"compile","path":"Hello","privateTab":true} +``` + +##### 返回结果 + +```json +{"result":"Hello_2020-08-17-09:09:40.ypk","action":"onCompile"} +``` + +#### 锁定私有目录 + +锁定某个用户的的私有目录编辑功能 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------------- | +| action | lockEdit | +| pubKey | string, 要被锁定的公钥 | + +##### 请求示例 + +```javascript +var req = {}; +req.action = "lockEdit"; +req.pubKey = "xxxxxx"; +wssocket.send(JSON.stringify(req)); +``` +```json +{ + "action":"onLockEdit", + "status":"success", + "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1" +} +``` + + +#### 解锁私有目录 + +解锁某个用户的的私有目录编辑功能 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------------- | +| action | unLockEdit | +| pubKey | string, 要被锁定的公钥 | + +##### 请求示例 + +```javascript +var req = {}; +req.action = unlockEdit; +req.pubKey = "xxxxxx"; +wssocket.send(JSON.stringify(req)); +``` +```json +{ + "action":"onUnlockEdit", + "status":"success", + "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1" +} +``` + + +### 合约实例管理类 + +#### 查询合约进程 + +向服务器发送请求, 查询服务器上已经启动的所有合约进程. + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------- | +| action | listContractProcess | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "listContractProcess"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "action": "onListContractProcess", + "data": "[...]" +} +``` + + + +#### 调用合约 + +向服务器发送请求, 调用某个合约. + +##### 参数 + +| 字段 | 值 | +| -------------------- | --------------------------- | +| action | executeContract | +| contractID | 合约ID | +| withDynamicAnalysis | true/false 是否进行动态分析,可选 | +| operation | 调用合约的方法名 | +| arg | 调用合约的参数 | +| pubkey | 调用者公钥,可选 | +| signature | 调用者签名 ,可选 | + +`*`表示可选参数 + +```javascript +//sm2 可从sm2.js中加载获得。 +signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey); +``` + +##### 请求示例 + +```javascript +var request = {}; +request.action = "executeContract"; +request.contractID = "2073401446"; +request.operation = "main"; +request.arg = "hhhhh"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "needSeq":false, + "seq":0, + "status":"Success", + "result":"world", + "isInsnLimit":false, + "totalGas":0, + "executionGas":0, + "extraGas":0, + "size":0, + "eventRelated":false, + "responseID":"1617211077264_223", + "action":"onExecuteResult", + "executeTime":"5" +} +``` + +#### 输出历史记录日志(删除) + +向服务器发送请求, 获取节点服务器上合约的TimeTravel日志. + +##### 参数 + +| 字段 | 值 | +| ------ | ------------------ | +| action | printTimeTravelLog | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "printTimeTravelLog"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "status": false, + "data": "[CMActions] dumpContract :…t/contractExamples/memoryDumps/LicenceManager\n" +} +``` + + + +#### 输出节点转移日志(删除) + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------- | +| action | printTransferLog | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "printTransferLog"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json + { + "status": false, + "data": "" +} +``` + + + +#### 合约状态迁移 + +向服务器发送请求, 获取节点服务器的状态转移日志. + +##### 参数 + +| 字段 | 值 | +| ------------ | ------------ | +| action | loadMemory | +| contractName | 合约名称 | +| memoryFile | 合约文件名称 | + +##### 请求示例 + +```javascript +var request = {}; +request.action = "loadMemory"; +request.contractName = "JsonContract"; +request.memoryFile = "2020-03-17.20/42/55"; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果示例 + +```json +{ + "data":"success", + "size":"0.00 B", + "action":"onTransferTo", + "time":"0.01s" +} +``` + + + +### 日志查看类 + +#### 查看本地近n日节点日志(删除) + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------- | +| action | listLocalNodeLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "listLocalNodeLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]" +} +``` + + + +#### 查看本地近n日合约日志(删除) + +##### 参数 + +| 字段 | 值 | +| ------ | -------------------- | +| action | listLocalContractLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "listLocalContractLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]" +} +``` + + + + +### 节点配置类 + +#### 获取节点配置信息 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | loadNodeConfig | + +##### 请求示例 + +``` +var param = {}; +param.action = "loadNodeConfig"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +``` +{ + "status": true, + "action": "onLoadNodeConfig", + "data": { + "nodeName": "04BF52213343C147E631B877BCEB17B794230EE551E85F58FA429C4BA03D690778CC384C6916C63DF36CB9E35C7E274FDB4E18491DFE3D611D347856D441CACC5AF9090B515F02AFC2DFBF56461EC83B5A4CD342466360D6CF82E6E40B637430AC4A329CCBC798DAF7D526AF9E3B3600E0BEA1BFAB8C160EF90128FAF67B19E45F37664F1E4B", + "licence": "04AADCC7103CD02626D228AFFBEF53F8242ECA4DDD6F179D30B622440666715CFBB6FD1D3678A2B25812DEA9917073E79A65F7ADE517F784DC76288EFCEB37ECAA1025E6903540702F729DA1C2ECCD93F4E6FAFCE40DF443E7FD74387169D0C6D927C7BB12882D0471C8D3E6F31B0316A42FC38F6DD9978D4351B23B2AD63E2244909E98F51185D32CB99B4AE4E22D3AB4C04027BB", + "expireTime": "Wed Aug 26 09:43:08 CST 2020", + "nodes": "[\"node1\",\"node2\",\"node3\"]", + "yjsPath": "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar", + "nodeCenter": "ws://127.0.0.1:1719/SCIDE/NodeCenter" + } +} + +{ + "status":true, + "action":"onLoadNodeConfig", + "data":{ + "nodeName":"Node_180", + "peerID":"", + "masterAddress":"39.104.201.40:21031", + "licence":"04AADCC7103C", + "doipConfig":"{\\"LHSProxyAddress\\":\\"http://39.104.201.40:21042/\\",\\"ownerHandle\\":\\"86.5000.470/dou.TEST\\",\\"certPath\\":\\"keys/dou.TEST.keystore\\",\\"certPassword\\":\\"123456\\",\\"repoID\\":\\"86.5000.470/doip.vcg9Mu1gSq_bdw\\",\\"listeners\\":\\"[{\\\\\\"url\\\\\\":\\\\\\"tcp://39.104.201.40:21032\\\\\\",\\\\\\"protocolVersion\\\\\\":\\\\\\"2.1\\\\\\",\\\\\\"messageFormat\\\\\\":\\\\\\"packet\\\\\\"}]\\",\\"serviceDescription\\":\\"test local Contract Repository\\",\\"serviceName\\":\\"ContractEngine021\\"}", + "clusterConnected":"false", + "nodePubKey":"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5", + "ipPort":"", + "bdledger":"39.108.56.240:18091,39.108.56.12:1809139.104.70.160:18091 47.98.247.70:18091 47.98.248.208:18091 39.104.77.165:18091 47.98.249.131:18091", + "yjsPath":"/data/bdwaas/bdcontract/yjs.jar", + "nodeCenter":"ws://39.104.201.21040/SCIDE/NodeCenter" + } +} +``` + + +#### 修改节点配置 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | updateConfig | +| key | 要改的配置项 | +| val | 要更改的目标值 | + +其中,key的可选项包括: + +| key的示 | val示例 | 说明 | +| ------------- | ----------------------------------- | ------------------------------- | +| yjsPath | /User/xxx/cp/yjs.jar | 合约进程启动所需的jar | +| dataChain | 192.168.1.8:18090,182.173.2.3:18091 | 账本节点的ip与端口 | +| nodeCenter | ws://127.0.0.1:18002 | CenterPortal所在的ip/端口 | +| nodeName | Node_180 | 字符串类型 | +| masterAddress | 192.168.3.2:18001 | 该NodePortal节点的ip和的TCP端口 | + +其中NodePortal的TCP端口为Node的http/ws端口号+1。 + + +#### 修改节点名称 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | changeNodeName | +| data | 新的节点名称 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeNodeName"; +param.data = "NewNodeName"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeNodeName", + "data": true +} +``` + + + +#### 修改节点YJS路径 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------- | +| action | changeYJSPath | +| data | 节点服务器yjs.jar路径 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeYJSPath"; +param.data = "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeYJSPath", + "data": true +} +``` + + + +#### 修改NodeCenter + +##### 参数 + +| 字段 | 值 | +| ------ | ----------------------------------------- | +| action | changeNodeCenter | +| data | 节点服务器要连接的NodeCenterWebSocket路径 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeNodeCenter"; +param.data = "ws://127.0.0.1:1719/SCIDE/NodeCenter"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeNodeCenter", + "data": true +} +``` + + + +#### 修改账本节点 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------------------- | +| action | changeBDledger | +| data | 数链节点的IP:port,用","隔开 | + +##### 请求示例 + +``` +var param = {}; +param.action = "changeBDledger"; +param.data = "39.108.56.240:18091,39.108.56.12:18091"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onChangeBDledger", + "data": true +} +``` + + + +#### 上传节点Licence + +##### 参数 + +| 字段 | 值 | +| ------ | ----------------------- | +| action | uploadLicence | +| data | 节点服务器的Licence内容 | + +##### 请求示例 + +``` +var param = {}; +param.action = "uploadLicence"; +param.data = "04AADCC7103C"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onUploadLicence", + "data": true +} +``` + + + +#### 获取节点ID + +##### 参数 + +| 字段 | 值 | +| ------ | --------- | +| action | getNodeID | + +##### 请求示例 + +``` +var param = {}; +param.action = "getNodeID"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "status": true, + "action": "onGetNodeID", + "data": "0431…d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d" +} +``` + + + +#### 获取节点所在的可信执行集群 + +##### 参数 + +| 字段 | 值 | +| ---------- | ------------------------------------------------ | +| action | getNodeTrustUnits | +| data | 节点ID | +| msgHandler | 收到回复的回调函数, 可使用"建立连接"的msgHandler | +| ws | 节点所属的NodeCenter的WebSocket地址 | + +##### 请求示例 + +``` +centerportalws = createWssocket("ws://127.0.0.1:1718/NodeCenterWS",function() { +var param = {}; +param.action = "getNodeTrustUnits"; +param.data = "0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d"; +centerportalws.send(JSON.stringify(param)); +}, msgHandler); +``` + +##### 返回结果 + +```json +{ + "data": [{ + "key": "0475c7b061...65e55_4063665700873624164", + "value": "[\"04541429c11b094…40009b4f06d\"]" + }], + "action": "onGetNodeTrustUnits" +} +``` + +### 模板生成类 + +#### 获取合约模板列表 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | getTemplateList | + +##### 请求示例 + +``` javascript +req={}; +req.action = "getTemplateList"; +wssocket.send(JSON.stringify(req)); +``` + +##### 返回结果 + +``` json +{ + "data": [ + { + "formDesc": { + "dbPWD": { + "label": "密码", + "type": "input" + }, + "contractName": { + "label": "合约名称", + "type": "input" + }, + "accessPolicy": { + "label": "访问控制策略", + "type": "input", + "option": [ + { + "text": "无访问控制", + "value": "NAC" + }, + { + "text": "直接访问控制", + "value": "DAC" + }, + { + "text": "基于角色的访问控制", + "value": "RBAC" + } + ] + }, + "dbUserName": { + "label": "用户名", + "type": "input" + }, + "fieldList": { + "label": "字段名", + "type": "tag" + }, + "dbUrl": { + "label": "数据库链接", + "type": "input" + }, + "tableName": { + "label": "表名", + "type": "input" + } + }, + "apiName": "generateMySQLProject" + }, + { + "formDesc": { + "contractName": { + "label": "合约名称", + "type": "input" + }, + "accessPolicy": { + "label": "访问控制策略", + "type": "input", + "option": [ + { + "text": "无访问控制", + "value": "NAC" + }, + { + "text": "直接访问控制", + "value": "DAC" + }, + { + "text": "基于角色的访问控制", + "value": "RBAC" + } + ] + } + }, + "apiName": "generateEmptyProject" + } + ], + "action": "onTemplateList" +} +``` + +#### 空白合约模板 + +##### 参数 + +| 字段 | 值 | +| ------------ | ----------------------------- | +| action | generateEmptyProject | +| contractName | 字符串类型,合约名称 | +| isPrivate | 布尔类型,是否为私有项目 | +| accessPolicy | 若为"DAC",则实现直接访问控制 | + +##### 请求示例 + +```javascript +var req = {}; +req.contractName = "Empty22"; +req.action = "generateEmptyProject"; +req.accessPolicy = "DAC"; +//wssocket为建立好的连接 +wssocket.send(JSON.stringify(req)); +``` + +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\"]", + "executeTime":0, + "isPrivate":false +} +``` + +#### MySQL接入合约 + +##### 参数 + +| 字段 | 值 | +| ------------- | ------------------------------------------------------ | +| action | generateMySQLProject | +| contractName | 字符串类型,合约名称 | +| isPrivate | 布尔类型,是否为私有项目 | +| dbUrl | 字符串类型,数据库的URI | +| dbUserName | 字符串类型,数据库的用户名 | +| dbPWD | 字符串类型,数据库密码 | +| accessPolicy | 若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制 | +| tableName | 字符串类型,数据库的表名 | +| fieldList | 字符串列表,数据库的字段列表 | +| defaultAccept | 布尔值,表示申请时是否默认有权 | + +##### 请求示例 + +```javascript +var req = {}; +req.contractName = "MySQLFromTemplate"; +req.action = "generateMySQLProject"; +req.pubKey = global.sm2Key.publicKey; +req.isPrivate = true; +req.tableName = "data"; +req.dbUrl = "jdbc:mysql://xxx:xxx/xxx"; +req.dbUserName = "loushuai"; +req.dbPWD = "loushuai"; +req.fieldList = [{"name":"名字","code":"*"}]; +req.basicInfo={"type":"所属分类","name":"资源名称"}; +req.accessPolicy = "DAC"; +req.defaultAccept = true; +//global.wssocket为建立好的连接 +global.wssocket.send(JSON.stringify(req)); +``` + +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true +} +``` +#### CSV接入合约 + +##### 参数 + +| 字段 | 值 | +| ----------------- | ------------------------------------------------------ | +| action | generateCSVProject | +| contractName | 字符串类型,合约名称 | +| base64EncodedData | 字符串类型,通过base64编码后的CSV文件内容 | +| isPrivate | 可选字段,布尔类型,是否为私有项目 | +| accessPolicy | 若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制 | +| defaultAccept | 可选字段,布尔值,表示申请时是否默认有权 | + +##### 请求示例 + +```javascript +var req = {}; +req.contractName = "CSVFromTemplate"; +req.action = "generateCSVProject"; +req.pubKey = global.sm2Key.publicKey; +req.isPrivate = true; +req.tableName = "data"; +req.accessPolicy = "DAC"; +req.defaultAccept = true; +req.base64EncodedData = "bmFtZSwgc2NvcmUsCmphY2ssIDkwLApsdWN5LCA5MQo="; +//global.wssocket为建立好的连接 +global.wssocket.send(JSON.stringify(req)); +``` +##### 返回结果 +```json +{ + "action":"onListProjects", + "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]", + "executeTime":0, + "isPrivate":true +} +``` + +- - - + +## 路由节点WebSocket接口 + +### 用户管理类 + +#### 获取Session + +登录前获取session以便进行签名。 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | getSessionID | + +##### 请求示例 + +``` +var req = {}; +req.action = "getSessionID"; +wssocket.send(JSON.stringify(req)); +``` + + +##### 返回结果 + +```json +{ + "action": "onSessionID", + "session": "9782323_session" +} +``` + + +#### 用户登录 + +用户进行公私钥身份验证,需先调用"getSessionID"获取sessionID以便于签名。 + +##### 参数 + +| 字段 | 值 | +| ------ | ----- | +| action | login | + +##### 请求示例 + +``` +var loginParam = {}; +loginParam.pubKey = global.sm2Key.publicKey; +loginParam.signature = sm2.doSignature(global.session, + global.sm2Key.privateKey); +loginParam.action = "login"; +wssocket.send(JSON.stringify(loginParam)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onLogin", + "data": "CenterManager" +} +``` + + + +#### 用户获取当前角色(删除) + +用户根据登录时的公钥获取对应的角色,如果是第一次登录则此时的公钥默认称为准入管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | ------- | +| action | getRole | + +##### 请求示例 + +``` +var param = {}; +param.action = "getRole"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onGetRole", + "data": "CenterManager" +} +``` + +#### 申请角色 + +在准入管理员界面可以申请称为组网中某个节点的节点管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | --------- | +| action | applyRole | +|role|申请的角色名称| + +##### 请求示例 + +``` +var param = {}; +param.action = "applyRole"; +param.role=" +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onApplyRole", + "data": "failed" +} +``` + + +#### 添加节点 + +##### 参数 + +| 字段 | 值 | +| ---------- | ---------------- | +| action | addNode | +| nodePubKey | 要添加的节点公钥 | + +#### 请求示例 + +``` +var req = {}; +//某节点的publicKey可通过连接该节点,并通过"获取节点配置信息"接口获取 +req.nodePubKey = publicKey; +req.action = "addNode"; +wssocket.send(JSON.stringify(req)); +``` + + +#### 删除用户角色 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | delete | +| pubKey | 对应用户的公钥 | + +##### 请求示例 + +``` +var deleteInfo = {}; +deleteInfo.pubKey = user.publicKey; +deleteInfo.action = "delete"; +wssocket.send(JSON.stringify(deleteInfo)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onDelete", + "data": "success" +} +``` + +#### 查看授权用户列表 + +查看准入管理员当前组网中已经授权的节点管理员 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------ | +| action | listAllUsers | + +##### 请求示例 + +``` +var param = {}; +param.action = "onListAllUsers"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onListAllUsers", + "kv": { + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": " NodeManager" + }, + "time": { + "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7", + "value": 1587398989914 + } +} +``` + +#### 查看申请用户列表 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------- | +| action | listApplyList | + +##### 请求示例 + +``` +var param = {}; +param.action = "onListApplyList"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onListApplyList", + "kv": { + "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7", + "value": " NodeManager" + }, + "time": { + "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7", + "value": 1587398989914 + } +} +``` + +#### 查看用户类型分布 + +##### 参数 + +| 字段 | 值 | +| ------ | ------------- | +| action | queryUserStat | + +##### 请求示例 + +``` +var param = {}; +param.action = "onQueryUserStat"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果示例 + +```json +{ + "action": "onQueryUserStat", + "userListCount": 3, + "applyListCount":0 +} +``` + +### 节点管理类 + +#### 查看节点列表 + +查看该用户有权限查看的节点列表(仅准入管理员及合约管理者可用) + +##### 参数 + +| 字段 | 值 | +| ------ | --------- | +| action | listNodes | + +##### 请求示例 + +``` +var param = {}; +param.action = "listNodes"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "offline": [{ + "key": "0431e31...40009b4f06d", + "value": "0431e311bd708...b4f06d" + }], + "action": "onListNodes", + "online": [{ + "contracts": [], + "pubKey": "0431e311...09b4f06d", + "nodeName": "NewNodeName", + "udpID": "528822126", + "cimanager": "" + }] +} +``` + + +#### 查看可信执行集群列表 + +查看该用户有权限查看的节点列表(仅中心管理员及合约管理者可用) + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | listTrustUnits | + +##### 请求示例 + +``` +var param = {}; +param.action = "listTrustUnits"; +wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "data": [{ + "key": "0470b2f27f4f6…1cb855f1ecec11", + "value": "[...]" + }], + "action": "onListTrustUnits" +} +``` + + +#### 建立可信执行集群 + +##### 参数 + +| 字段 | 值 | +| ------ | ---------------------- | +| action | createTrustUnit | +| data | 节点公钥组成的Json数组 | +| Msg | 集群名称 | + +##### 请求示例 + +``` +var param = {}; +param.action = "createTrustUnit"; +param.data = "[\"382r0934309t...\",\"345343rr3f34...\"]"; +param.msg = "newUnit1"; +global.wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onCreateTrustUnit", + "status": "Success" +} +``` + + +#### 删除可信执行集群 + +##### 参数 + +| 字段 | 值 | +| ------ | --------------- | +| action | deleteTrustUnit | +| data | 可信执行集群ID | + +##### 请求示例 + +``` +var param = {}; +param.action = "deleteTrustUnit"; +param.data = "0475d34rf3434..._1583410158761"; +global.wssocket.send(JSON.stringify(param)); +``` + +##### 返回结果 + +```json +{ + "action": "onDeleteTrustUnit", + "status": "Success" +} +``` + + + +### 日志查看类 + +#### 查看组网管理操作的统计 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------- | +| action | queryActionLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "onQueryActionLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ "action":"onQueryActionLog", + "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]" +} +``` + + + +#### 查看本地近n日合约日志 + +##### 参数 + +| 字段 | 值 | +| ------ | -------------------- | +| action | listLocalContractLog | +| date | 当前时间 | + +##### 请求示例 + +``` +request.action = "listLocalContractLog"; +request.date = new Date().getTime() - 24 * 3600 * 1000 * n; +wssocket.send(JSON.stringify(request)); +``` + +##### 返回结果 + +```json +{ + "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7b...\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]" +} +``` + + +- - - + +## Bash接口 + +已废弃。可使用BDWareConfigTool代替。 +通过命令行发送Socket指令, 执行调用`ContractController`类中方法, 完成以下功能. (需要在本机的`1615`端口运行`ContractManager`实例) + +![Bash接口功能示意图](./_static/imgs/bash-api.png) + +### 指令 + +```bash +java -jar yjs.jar function_name arguments + +``` + +`function_name`为调用的方法名; + +`arguments`为方法参数. + +### 启动合约 + +#### 参数 + +`function_name`为`startContract`; + +`arguments`为启动合约需要的参数, 包括合约类型`type`, 合约ID`id`, 合约脚本`script`. + +#### 指令示例 + +```bash +java -jar yjs.jar startContract "{\"type\":\"Algorigthm\",\"id\":\"656565\",\"script\":\"contract c{function main(arg){return arg/1.0+1;}}\"}" +``` + +### 调用合约 + +#### 参数 + +`function_name`为`executeContract`; + +`arguments`为调用合约需要的参数, 包括调用参数`arg`, 合约ID`contractID`. + +#### 指令示例 + +```bash +java -jar yjs.jar executeContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}" +``` + +### 停止合约 + +#### 参数 + +`function_name`为`stopContract`; + +`arguments`为调用合约需要的参数, 即合约ID`contractID`. + +#### 指令示例 + +```bash +java -jar yjs.jar stopContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}" +``` + +### 停止全部合约 + +#### 参数 + +`function_name`为`stopAllContracts`. + +#### 指令示例 + +```bash +java -jar yjs.jar stopAllContracts +``` + +### 查询全部合约 + +#### 参数 + +`function_name`为`listContracts`. + +#### 指令示例 + +```bash +java -jar yjs.jar listContracts +``` + \ No newline at end of file diff --git a/doc/_sources/markdown_BDWare/IDEUsage.md.txt b/doc/_sources/markdown_BDWare/IDEUsage.md.txt new file mode 100644 index 0000000..34de595 --- /dev/null +++ b/doc/_sources/markdown_BDWare/IDEUsage.md.txt @@ -0,0 +1,439 @@ +# 管理界面 + +- - - + +## 合约节点管理界面 + +该界面的使用地址为:[NodePortal.html](/NodePortal.html) + + +### 用户管理菜单 +用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。 + +#### 概览 +![nodeUserManager](./_static/imgs/nodeUserManager.jpg) +节点用户管理页面一共有四个模块:用户情况、用户活跃统计、授权用户管理、未授权用户管理。 + +#### 用户类型分布 +主要统计当前节点管理员所拥有的四种角色的数量:合约提供者、合约管理员、合约使用者 +![userList](./_static/imgs/userList.jpg) + +#### 用户活跃统计 +![userActive](./_static/imgs/userActive.jpg) +统计30天之内**登录**、**授权**、**申请**的次数 + +#### 当前用户信息 +![nodeInfo](./_static/imgs/nodeInfo.jpg) + * 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录节点管理员界面,可以将自己的公私钥复制到这个文本框中。 + * 将自己的公私钥复制完成之后要点击**导入公钥**,将公钥加入到节点管理员本地 + * 然后在**本地公钥**中可以看见公钥的前五位,选择自己的公钥,将在**我的权限**中展示出当前选择的公钥的角色,如果是还没有在中心管理员认证的节点则默认为**Anonymous** + * 如果不是节点管理员,想要加入某个中心管理员的网络,那么要在中心管理员所在的用户管理中用自己的公私钥导入后进行认证。 + * 如果想要行使更多关于合约的操作,则需要认证不同的角色:合约管理员、合约使用者、合约提供者,然后进行**角色认证** + +#### 授权与非授权用户列表 +![roleAuth](./_static/imgs/roleAuth.jpg) + 在节点管理员认证角色之后,节点管理员登录会在**未授权角色管理**表格中看见带有公钥的申请信息,如果同意,则点击**授权**,如果不同意点击**忽略**就可以。 + 授权之后将在**授权角色管理**表格中看见授权后的节点列表。如果节点管理员想要移除某个节点的角色,则在授权角色管理列表中**删除**即可。 + +### 合约代码管理菜单 + +![codeManageMenu](./_static/imgs/codeManageMenu.png) + + + +#### 合约文件 + +![codeManage1](./_static/imgs/codeManage1.png) + +在合约代码管理菜单中,用户可以看到公共合约以及个人私有合约。 +![codeManage1-1](./_static/imgs/codeManage1-1.png) + +对于公共合约,节点管理员可以对其中文件进行删除和上传操作,可以对合约项目进行下载和删除操作。 +![codeManage1-2](./_static/imgs/codeManage1-2.png) + +对于私有合约,合约提供者可以对其中文件进行删除和上传操作,可以对合约项目进行下载、删除和传至公共合约目录操作。 + +以下是对合约文件进行操作的示例。 + +#### 上传文件 +![codeManage6](./_static/imgs/codeManage6.png) + +#### 删除 +![codeManage5](./_static/imgs/codeManage5.png) + +#### 传至公共 +![codeManage7](./_static/imgs/codeManage7.png) + +#### 下拉框 + +![codeManage2](./_static/imgs/codeManage2.png) + +四个下拉框中,可以分别对合约状态保存模式、已启动合约实例、节点所在集群以及结果校验方式进行选择。 + + + +#### 按钮操作 + +![codeManage3](./_static/imgs/codeManage3.png) + +#### 启动 + +在文件列表中选择合约文件之后,在合约运行模式中选择“单节点执行”,点击启动按钮,会启动指定文件,并在结果显示框中显示返回结果。 + + + +#### 启动P2P集群合约 + +在文件列表中选择合约文件之后,在合约运行模式中选择该可信合约运行的合约集群,点击启动按钮,会在该集群的所有节点上启动指定文件,并在结果显示框中显示返回结果。 + + + +#### 启动全部 + +在合约运行模式中选择“单节点执行”,点击启动全部按钮,会启动合约文件列表中所有合约。 + + + +#### 停止P2P集群合约 + +在已启动合约实例的下拉框中选择一个合约实例,在合约运行模式中选择该可信合约运行的合约集群,点击停止按钮,会在该集群的所有节点上终止这个合约进程。 + + + +#### 停止 + +在已启动合约实例的下拉框中选择一个合约实例,点击停止按钮,会终止这个合约进程。 + + + +#### 停止全部 + +点击停止全部按钮,会停止该节点上运行的所有合约实例。 + + + +#### 静态分析 + +在合约文件列表中选择合约文件,并在合约实例下拉框中选择合约实例,点击静态分析按钮,会对该合约进行静态分析,并在结果显示框中显示返回结果。 + + + +#### 分发合约 + +在合约文件列表中选择合约项目,并在合约运行模式中选择一个集群,点击分发合约按钮,会将该合约项目打包为ypk分发给这个集群中的所有节点。 + + + + +#### 返回结果 + +![codeManage4](./_static/imgs/codeManage4.png) + +返回结果显示中显示一些操作的返回结果。 + + + +#### 合约权限配置 + +在启动合约之后,如果当前用户的角色可以查看已经启动合约进程,那么在选定查看合约进程时将会在右下方展示当前合约的IO权限。 +![permissionShow](./_static/imgs/permissionShow.png) + +如果选中的合约没有IO权限,则在当前权限的展示框中提示**当前合约没有IO权限** +![nullPermission](./_static/imgs/nullPermission.png) + +当前用户是合约管理员时可以对已有的合约IO权限进行修改。系统会提示修改后合约将有可能不会正常运行,如果还是确定要取消,那么点击**确定** 即可,反之点击**关闭** +![updatePermission](./_static/imgs/updatePermission.png) + +点击关闭或者打开之后,下一次查看同一个合约代码的进程将会默认显示最近一次修改之后的IO权限。 +![closePermission](./_static/imgs/closePermission.png) + +### 合约实例管理菜单 + +![nodeInstancesPage](./_static/imgs/nodeInstancesPage.png) + +合约实例管理菜单显示了该节点当前的所有合约实例, 用户可查看合约实例的状态, 并对合约实例进行执行或状态迁移的操作. + +#### 合约实例列表 + +![nodeInstancesList](./_static/imgs/nodeInstancesList.png) + +该列表显示了当前节点的所有合约实例信息, 包括合约ID, 合约名称, 合约类型合约状态, 合约进程端口, 合约调用次数, 合约流量, 及合约占用内存, 集群合约的结果校验模式. + +#### 合约实例执行 + +![chooseInstance](./_static/imgs/chooseInstance.png) + +用户可在合约实例的选择下拉框中选择合约实例, 对该合约实例进行操作. + +![intanceExecute](./_static/imgs/intanceExecute.png) + +选择合约实例后, 用户可在"方法"的下拉框中选择该合约的方法名, 在"参数"输入框中输入方法的参数, 点击"执行". + +用户还可点击"动态分析执行"进行带有动态分析结果的执行. + +若该合约为单点合约, 则合约在单点执行; 若该合约为集群合约, 则该合约在该集群的所有节点上执行. + +#### 合约实例执行结果 + +![executeResult](./_static/imgs/executeResult.png) + +合约实例的执行完成后的结果显示在"执行结果"区域中, 包括该次执行的ID, 执行成功/失败, 执行时间, 及执行结果. + +![analysisExecuteResult](./_static/imgs/analysisExecuteResult.png) + +若该合约的执行方式为"动态分析执行", 则结果框内除执行结果, 还会显示该次执行的动态分析结果. + +#### 合约状态迁移 + +![memoryDump](./_static/imgs/memoryDump.png) + +对于支持用户手动迁移的合约实例, 用户可点击"本地状态保存"对合约实例的状态进行保存, 或从合约的TimeTravel列表中选择已保存的合约实例, 将合约状态迁移到对应时刻. + + + +### 日志管理菜单 +![logMenu](./_static/imgs/logMenu.png) + +该菜单是对该节点本地节点日志以及合约日志的统计结果展示。 + +其中,节点管理员可以查看节点日志的相关数据;合约管理者及合约使用者可以查看该节点本地合约日志的相关数据。 + + + +#### 日志统计图 + +![log1](./_static/imgs/log1.png) + +#### 各类平台操作百分比 + +该图默认显示近2日各类平台操作占比的饼图,其中平台操作分为登陆类、用户类、日志类、合约类、维护类以及其他类这六类。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比会同步更新。 + + + +#### 各类合约操作百分比 + +合约操作分为启动、终止、静态分析和执行这四类,该图为近2日对各类合约操作占比的饼图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比会同步更新。 + + + + +#### 每日平台使用统计 + +该图为近2日平台操作次数统计的折线图。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日平台使用统计折线图会同步更新。 + + + + +#### 每日合约使用统计 + +该图为近2日对该节点上合约的操作次数统计的折线图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日合约使用统计折线图会同步更新。 + + + + +#### 日志详情 + + + +#### 节点日志详情 +![log2](./_static/imgs/log2.png) + +节点日志详情表是对节点日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比和每日平台使用统计会同步更新。 + + + +#### 合约日志详情 +![log3](./_static/imgs/log3.png) + +合约日志详情表是对合约日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比和每日合约使用统计会同步更新。 + + + +### 节点管理菜单 + +![nodeConfig](./_static/imgs/nodeConfig.png) + +节点管理菜单显示了该节点的配置信息及所属可信执行集群信息. + +#### 节点配置 + +![nodeConfigChange](./_static/imgs/nodeConfigChange.png) + +节点管理员可查看该节点的配置信息, 包括节点名称, 节点YJS路径, 节点的网络中心节点, 节点管理员还可对以上配置进行修改. + +若节点管理员修改了节点的网络中心, 该节点后重新想改节点连接, 整个页面刷新重载. + +#### 节点可信执行集群列表 + +![nodeUnits](./_static/imgs/nodeUnits.png) + +节点管理员可查看节点所属的可信执行集群信息, 包括集群创建者, 集群ID, 集群中节点数目, 集群中节点的信息. + +- - - + +#### 节点Licence配置 + +![nodeLicence](./_static/imgs/nodeLicence.png) + +用户可以查看该节点的Licence及过期时间, 还可申请Licence, 上传Licence, 保存节点UUID. + +## 智能合约在线编辑器 + +### 用户与账号 + +#### 创建账号 + +#### 申请授权 + + +### 创建项目 + +#### 新建文件 + +#### 上传文件 + +### 启动合约 +![contractMode](./_static/imgs/contractMode.png) + +####正常模式 +点击左侧启动按钮,以正常模式启动合约。 + +####debug模式 +点击右侧debug按钮,以debug模式启动合约。目前约定debug模式合约通过executeContract调用正常模式合约时,返回正常模式合约文档中的返回结果示例。 + +### 调用合约 + +###生成文档 +![genReadme](./_static/imgs/genReadme.png) + +启动合约后点击"生成文档"按钮,可以通过各export函数的@Description / @Param / @Result 对合约进行调用及结果返回,从而生成合约的说明文档。 + +- - - + +## 路由准入管理界面 + +### 权限申请与授权 + +### 仪表盘 +仪表盘为提供对准入节点中用户数量,合约数量,节点数量的概览。 + +### 整体视图 +![dashboard](./_static/imgs/dashboard.jpg) +一共分为四个模块,一个模块是用户、合约、节点数量的概览,然后分别是这三个数量的详细分类的数据统计情况。 + +### 节点数目 +![node](./_static/imgs/node.jpg) +当前在线和离线节点统计 + +### 用户类型分布 +![userAll](./_static/imgs/userAll.jpg) +当前准入节点所在组网中的节点管理员、准入管理员的数量和申请中节点的数量 + +### 合约调用情况 +![contract](./_static/imgs/contract.jpg) +当前准入节点所在组网中所有合约中事件、多点执行、ws调用、Http调用的折线统计图。 + +### 用户管理 +用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。 + +### 概览 +![centerManager](./_static/imgs/centerManager.jpg) +用户管理页面一共有四个模块。 + + +### 用户类型分布 +主要统计当前中心管理员所管理的网络中有多少节点管理员,多少个中心管理以及申请节点管理员的数量 +![userList](./_static/imgs/userList.jpg) + +### 30天内的申请情况统计 +![userApplyGraph](./_static/imgs/userApplyGraph.jpg) +统计30天之内申请节点管理员的数量和授权成为节点管理员的数量 + +### 当前用户信息 +![authNodeManager](./_static/imgs/authNodeManager.jpg) + * 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录中心管理员界面,可以将自己的公私钥复制到这个文本框中。 + * 将自己的公私钥复制完成之后要点击**导入公钥**,将公钥加入到中心管理员本地 + * 然后在**本地公钥**中可以看见公钥的前五位,选择自己的公钥,将在**我的权限**中展示出当前选择的公钥的角色,如果是中心管理员则拥有中心管理员的一切权限。 + * 如果不是中心管理员或者节点管理员,想要加入当前中心管理员的网络,那么可以在下面的选择框中选中节点管理员,进行**角色认证**。 + +### 授权与非授权用户列表 + 在中心管理员当前用户信息申请之后,中心管理员登录会在**未授权用户管理**表格中看见带有公钥的申请信息,如果同意,则点击**授权**,如果不同意点击**忽略**就可以,此时这个申请就无效。 +![authMan](./_static/imgs/authMan.jpg) + 授权之后将在**授权用户管理**表格中看见授权后的节点列表。如果中心管理员想要移除某个节点管理员的某项角色,则在授权用户管理列表中选择相应的角色,然后点击**删除**即可删除选中的角色。 +![authMana](./_static/imgs/authMana.jpg) + +### 节点管理 + +![centerNodePage](./_static/imgs/centerNodePage.png) + +节点管理为Manager对连接到自己的Cluster节点进行管理的页面, 仅Manager管理员及合约管理者可见. Manager管理员及合约管理者可在本页面查看节点信息, 并管理可信执行集群. + +### 概览 + +![centerNodePreview](./_static/imgs/centerNodePreview.png) + +概览中显示了该Manager节点所管理的所有节点的统计信息, 包括总节点数量, 总合约数量, 总订阅事件数量, 及可信执行集群数量, 右侧的饼图则为节点的分别处于Online/Offline的数量统计. + +### 节点列表 + +![centerNodeList](./_static/imgs/centerNodeList.png) + +节点列表显示了用户有权限查看的节点信息(Manager管理员可查看全部节点, 合约管理者可查看自己负责管理的Online节点). 包括节点的名称, 状态, 合约数目, 订阅事件数目, 用于节点间P2P通信的PeerID, 用于节点间UDP通信的UDPID, 及节点公钥. + +### 可信执行集群列表 + +![centerNodeUnits](./_static/imgs/centerNodeUnits.png) + +可信执行集群列表显示了用户有权限查看的可信执行集群信息(Manager管理员可查看全部集群, 合约管理者可查看自己创建的集群). 包括集群的创建者, 集群ID, 集群中节点数目, 以及集群中节点的信息. + +用户可点击列表表项的"删除"按钮, 将该集群删除. + +### 创建可信执行集群 + +![centerNodeUnitCreate](./_static/imgs/centerNodeUnitCreate.png) + +用户可以通过多选节点, 创建新的可信执行集群. 用户可以选择的节点为自己有权限查看的节点, 即Manager管理员从全部节点中选择, 合约管理者可从自己负责管理的Online节点中选择). 选择后点击提交, 即可看到创建成功的提示信息, 该集群将随即显示在可信执行集群列表中. 集群名称由创建者选取, 不能含有双引号, 该名称为合约管理者选择集群时的可见标识. + +### 日志管理 +日志管理主要展示准入节点的各项日志信息,一共分为六个模块。 +### 概览 +![log](./_static/imgs/log.jpg) + +### 管理操作分类统计(2日) +![operator](./_static/imgs/operator.jpg) +两日内所有管理类操作的统计饼图,管理类操作主要分为登录类、日志类、维护类、用户类。 + +### 管理操作每日统计(2日) +![everyLog](./_static/imgs/everyLog.jpg) +两日内管理类所有的操作每日操作统计 + +### 合约操作分类统计(2日) +![contractLog](./_static/imgs/contractLog.jpg) +两日内合约操作分类统计饼图,合约操作主要分为连接类和状态更新类。 + +### 合约操作每日统计(2日) +![contracteveryLog](./_static/imgs/contracteveryLog.jpg) +两日内合约操作数量折线统计图。 + +### 管理操作日志列表 +![opList](./_static/imgs/opList.jpg) +管理操作日志的详细信息列表。包括日志时间,管理操作名称,操作对应的节点公钥。默认展示范围是两天,可以自定义获取日志的天数。 + +### 合约操作日志列表 +![contractList](./_static/imgs/contractList.jpg) +合约操作日志详细信息列表。包括日志产生时间,合约操作名称,合约操作节点公钥。默认展示范围是两天,可以自定义获取日志的天数。 + +### 设置 + +设置页面是节点证书的状态展示以及配置节点证书 + +### 概览 +![set](./_static/imgs/set.jpg) + +### 证书状态 +![licence](./_static/imgs/licence.jpg) +证书状态主要包括许可到期时间和许可节点数量。 + +### 配置证书 +![plicence](./_static/imgs/plicence.jpg) +配置证书模块可以下载节点ID文件或者输入证书信息进行提交。 diff --git a/doc/_sources/markdown_BDWare/InstallTips.md.txt b/doc/_sources/markdown_BDWare/InstallTips.md.txt new file mode 100644 index 0000000..e94eafb --- /dev/null +++ b/doc/_sources/markdown_BDWare/InstallTips.md.txt @@ -0,0 +1,190 @@ +# 安装说明 + + +- - - + +## 依赖环境的安装 +1.安装Java1.8环境。 + +例如,在Ubuntu下使用apt-get进行安装: + +```bash +apt-get install openjdk-8-jre +``` +在Centos环境下,使用yum进行安装: + +```bash +yum install java-1.8.0-openjdk +``` + +如果是离线环境,可先下载openjdk的安装包后进行离线安装。 + +Ubuntu下 +```bash +dpkg -i jdk-8uxxxxx.deb +``` + +在Centos环境下,使用yum进行离线安装: +```bash +yum localinstall jdk-8u271-linux-xxx.rpm +``` + +2.安装wget与unzip。 +例如,在Ubuntu下使用apt-get进行安装: + +```bash +apt-get install unzip +apt-get install wget +``` + +- - - + +## 网络拓扑说明 + +部署数瑞智能合约引擎最小仅需一个节点,此时可用作调试、测试,不能通过多节点模式来实现可信的计算。 +单节点部署时,可通过配置账本实现"防抵赖"的计算,但不能实现"难篡改"的计算。 + +多节点部署时可参考下图,包含三种逻辑节点,同一虚拟机可安装一至三种节点。 + +1)账本节点。即数瑞图式账本。 + +2)合约节点。运行代码逻辑,并通过内存缓存实现高响应的模块。与其他合约节点组成可信计算网络。 + +3)路由节点。各个合约节点的路由信息。一般单个路由节点可支持最高1000合约节点。可视情况部署多个路由节点,并在路由节点之间配置实现更大规模的节点组网。 + +一般地,同一虚拟机下,会部署**合约节点与账本节点**。 + +![deploytopology](_static/imgs/deploytopology.png) + +- - - + +## 智能合约节点安装 + +打开[安装包下载链接](https://public.internetapi.cn/?dir=releases/bdcontract/newest) +其中,下载`bdserver-lite.zip`或`bdserver.zip`,其中,`bdserver.zip`包含更多示例和文档。 +下载之后解压并启动。 + +```bash +unzip -d ./bdserver bdserver-lite.zip +cd bdserver +chmod +x *.sh +sh cmstart.sh +``` + +- - - + +## 路由准入节点安装 + +打开[安装包下载链接](https://public.internetapi.cn/?dir=releases/bdcontract/newest) +其中,下载`bdserver-cluster.zip`。 +下载之后解压并启动。 + +```bash +unzip -d ./bdcluster bdserver-cluster.zip +cd bdcluster +chmod +x *.sh +sh ncstart.sh +``` + +- - - + +## 文件说明 + +### 智能合约节点 + +![bdserver目录](_static/imgs/dirstructure.png) + +该目录下的文件说明: + +1.cmstart.sh 该脚本用于启动合约引擎。合约引擎默认监听8080端口,可通过修改cmstart.sh来修改合约引擎的监听端口。 + +2.BDWareProjectDir 该目录存放了本节点的所有合约项目。 + +3.WebContent 该目录存放了本节点的前端代码。 + +4.cp, 该目录存放了yjs.jar,为启动合约实例所需的jar。 + +5.bdserver.jar 对外提供http/websocket的服务器逻辑。 + +6.updateContract.sh 用于升级的脚本。 + +### 路由准入节点 + +安装脚本会自动下载安装并解压为bdcluster目录。 +该目录下的文件说明: + +1.ncstart.sh 该脚本用于启动节点准入中心。默认监听1718端口。可通过修改ncstart.sh来修改监听的端口。 + +2.WebContent 该目录存放了准入中心的前端代码。 + +3.bdcluster.jar 准入中心的后端。 + +- - - + +## 升级流程 + +### 合约节点 + +在命令行中输入: + +```bash +sh updateContract.sh +``` + +亦可通过[public.internetapi.cn](https://public.internetapi.cn/?dir=releases/bdcontract),下载最新文件,单独升级yjs.zip/bdserver-jar.zip/AgentWebContent来升级。 + +### 路由准入节点 + +```bash +sh updateCluster.sh +``` +亦可通过[public.internetapi.cn](https://public.internetapi.cn/?dir=releases/bdcontract),下载最新文件,单独升级bdserver-cluster.zip/ClusterWebContent.zip来升级。 + +- - - + +## 使用说明 + +### 通过参考界面使用 +当保留了WebContent目录的情况下,可使用浏览器进行配置。 +更多请使用见左侧文档[BDContract参考界面使用说明](./IDEUsage.html)。 + +#### BDWare OnlineIDE +打开[BDWare OnlineIDE](../OnlineIDE.html)。 + +#### BDWare NodePortal +打开[BDWare NodePortal](../NodePortal.html)。 + +如需组网,使用跨节点功能,则需安装路由准入中心。并按以下步骤进行配置。涉及两组公私钥。 +第一组公私钥为合约节点的、有NodeManager权限的公私钥。 +第二组公私钥为路由准入节点的、有CenterManager权限的公私钥。 + +1.打开NodePortal.html,复制该节点的NodeManager公私钥。 + +2.打开CenterPortal.html,点击右上角,将上述的NodeManager公私钥导入;并选择"NodeManager"进行身份认证。 + +3.在CenterPortal.html中切换CenterManager的公私钥,点左侧的"用户管理",通过NodeManager的认证请求。 + +4.使用NodeManager权限的公私钥打开NodePortal.html,点击:“节点管理”菜单,并配置加入网络。 +其中,加入网络的格式为:ws://centerportal的ip:端口+1。 +![配置示例](_static/imgs/config.png) + + +### 通过SDK使用 + +#### 基础知识 + +[Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) + +[Sm2加密的使用](https://github.com/JuneAndGreen/sm-crypto) + +#### SDK下载 + +1. Java版本的客户端下载:[BDWareJavaClient](_static/BDWareJavaClient.zip)。具体使用说明请下载后解压,查看README.md,并参考[ContractAPI](./ContractAPI.html)。 + +2.Javascript版本的客户端下载:[BDWareWebClient](_static/BDWareWebClient.zip)。具体使用说明请下载后解压,查看README.md,并参考[ContractAPI](./ContractAPI.html)。 + +3.配置工具[BDWareConfigTool](_static/BDWareConfigTool.zip)。具体说明请下载后解压,使用以下命令查看帮助: + +``` bash +java -jar java-client.jar -h +``` \ No newline at end of file diff --git a/doc/_sources/markdown_BDWare/Introduction.md.txt b/doc/_sources/markdown_BDWare/Introduction.md.txt new file mode 100644 index 0000000..59be7f8 --- /dev/null +++ b/doc/_sources/markdown_BDWare/Introduction.md.txt @@ -0,0 +1,54 @@ +# 北大数瑞介绍 + +- - - + +## 什么是北大数瑞? + + 北大数瑞是面向大数据场景的数据资源、IoT资源、云资源的管理、调度平台。BDContract是一个可信计算框架,计算逻辑以智能合约的方式表达。通过”随机“和”冗余计算“的方式实现智能合约的可信执行。BDContract在保证智能合约的可用性、可靠性的同时,着重提升执行效率和安全性。 + + +- - - + +## 特点 + +0. 支持多种执行模式,权衡可用性、可靠性、正确性和效率。 +1. 接入各种数据源。 +2. 支持合约的细粒度监测。 +3. 支持合约的状态。 +4. 访问控制。 +5. 支撑跨语言调用。 + + +- - - + + +## 使用开源项目说明 +BDWare项目站在了许多巨人的肩膀上,感谢这些开源项目。 + +本项目的智能合约后端使用了以下开源库。 + +| 名称 | Licence类型 | 说明 | +| ------ | ---------- | ---- | +| [Project Nashorn](https://openjdk.java.net/projects/nashorn/) | [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) | 使用了该项目的编译器,可以将js函数编译为java字节码 | +| [ASM OW2](https://projects.ow2.org/view/asm/) | [BSD](https://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_(original_%22BSD_License%22)) with attribution | 基于asm的TreeAPI与VisitorAPI实现合约的静态分析框架 | +| [Netty](https://netty.io/) | [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) | 使用netty作为Http/Websocket的服务端 | +| [gRPC](https://grpc.io/) | [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) | 使用gRPC与BDWareLedger通讯 | +| [RocksDB](https://github.com/facebook/rocksdb) | [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) | 后台数据库 | +| [ANTLR](https://github.com/antlr/antlr4) | [BSD](https://en.wikipedia.org/wiki/BSD_licenses#4-clause_license_(original_%22BSD_License%22)) | 对合约脚本的词法分析与语法分析 | +| [SM2Java](https://github.com/PopezLotado/SM2Java) | [无](https://github.com/PopezLotado/SM2Java/blob/master/README.md) | 国密SM2 Java语言实现 | + + + +本项目的智能合约前端使用了以下开源库。 + +| 名称 | Licence类型 | 说明 | +| ------ | ---------- | ---- | +| [Bootstrap](https://getbootstrap.com/) | [MIT](https://github.com/twbs/bootstrap/blob/master/LICENSE) | 前端的排版、样式 | +| [jQuery](https://jquery.org/) | [MIT](https://jquery.org/license/) | 用于操作DOM的javascript库 | +| [jQueryUI](https://jqueryui.com/) | [MIT](https://jquery.org/license/) | 前端UI构件库 | +| [DataTables](https://datatables.net/) | [MIT](https://datatables.net/license/mit) | 表格样式 | +| [CodeMirror](https://codemirror.net/) | [MIT](https://codemirror.net/LICENSE) | 代码编辑框样式 | +| [eCharts](https://echarts.apache.org/zh/index.html) | [ApacheV2](https://www.apache.org/licenses/) | 统计图表 | +| [sm-crypto](https://github.com/JuneAndGreen/sm-crypto) | [MIT](https://github.com/JuneAndGreen/sm-crypto/blob/master/LICENCE_MIT) | 国密SM2 javascript语言实现 | + +本项目的文档使用[Sphinx](https://www.sphinx-doc.org/en/master/)生成,感谢[readthedocs](https://readthedocs.org/)提供文档样式。 \ No newline at end of file diff --git a/doc/_sources/markdown_BDWare/YJSAPI.md.txt b/doc/_sources/markdown_BDWare/YJSAPI.md.txt new file mode 100644 index 0000000..d547272 --- /dev/null +++ b/doc/_sources/markdown_BDWare/YJSAPI.md.txt @@ -0,0 +1,1136 @@ +# YJS SDK +## YJS Build-in API + +### 内置对象 Global + + +### 内置对象 requester +该内置对象在export function里面会有值,仅当合约调用签名验证通过。 + + +### 执行合约 executeContract + +参数: + +``` bash +action:executeContract; +contractID:合约的id或名称均可; +operation:调用合约的方法名; +arg: 参数;格式为JSON字符串,有action与arg两个字段。 +``` + +可选参数: + +```bash +requestID:字符串类型,自行生成,用于查询hash +``` + +使用示例: + +```javascript + + function testExecutorContract(arg){ + var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg)); + if (ret.status == "Success"){ + return JSON.parse(ret.result); + }else return null; + } +``` +### 订阅事件主题 subscribe + +参数 + +``` bash +contractID:字符串类型 合约id或名称均可。 +event:字符串类型 +handler:方法名,该方法必须接受Event(内含字段topic和content)类型的唯一变量为参数;可以不是export方法 +``` + +使用示例: + +```javascript +export function init(arg) { + YancloudUtil.subscribe("topic", handler); + print("Handler: " + handler); +} + +function handler(e) { + print("topic: " + e.topic); + print("content: " + e.content); +} + +``` + +## 发布事件 pubEvent + +参数 + +``` bash +topic:字符串类型,发布的事件主题 +content:字符串类型,发布的事件内容 +``` +使用示例: + +```javascript +export function pub1(arg) { + YancloudUtil.pubEvent("topic", arg); + return "done"; +} +``` + +也可以在合约开头定义事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件 + +```javascript +event topic; +export function pub2(arg) { + topic(arg); + return "done"; +} +``` + +该写法与上面的`pub1`等价。 + + +### 访问资源文件 + +通过Global.Resources去加载ypk内部的资源文件。 + +#### loadAsInputStream + +参数: + + ```bash + path:字符串类型 需要加载文件的地址 + ``` + 使用示例: + + ```javascript + var file = Global.Resources.loadAsInputStream("/deleteit.txt"); + ``` + +#### loadAsScanner + +参数: + + ```bash + path:字符串类型 需要加载文件的地址 + ``` + + 使用示例: + + ```javascript + var scanner = Global.Resources.loadAsScanner("/local.txt"); + ``` + + + +## YJS Build-in Annotation + +### @Access + +设置合约的调用是否需要签名,这里分为两种,需签名和无签名。 +其中,"verified"表示需要签名。其他则表示无需签名。 + +``` +@Access("verified") +export function easy(arg){ + return "true"; +} +``` + +### @LogType + +LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。 + +其中,Arg表示日志中记录合约执行的参数;Result表示记录合约执行的返回结果;Branch表示记录合约执行分支。 + +例如 ,通过如下LogType注解来声明函数 + +``` +@LogType("Arg","Result","Branch") +export function easy(arg){ + Global.a = "a"; + Global.b = "b"; + if(arg > 0) + return Global.a; + else + return Global.b; +} +``` + +### @LogLocation + +该注解可以修饰`contract`或`function`。 +设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地,如果没有指定为“dataware”则仅存储在本地。 +例如,通过如下LogLocation设置存储位置。 + +在BaaS平台中,可以指定账本名称,BaaS平台默认账本为default,使用 +`@LogLocation("bdledger:default")`。如想保存到自定义的账本,比如,"abc"账本,就使用 +`@LogLocation("bdledger:abc")` + +``` +@LogLocation("dataware") +export function easy(arg){ + Global.a = "a"; +} +``` + + +### @Permission +该注解只能修饰`contract` +设置合约中调用的工具类的权限,包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类,需要在注解中添加对应的授权字段,默认只有YJS自带的YancloudUtil;如果没有添加则会抛出"未授权工具类"的异常。 +这6种工具类的详细说明在本小节后续中有说明。 + +``` +@Permission("Http","File") +contract HttpPermission { + export function main(args){ + var http=HttpUtil.httpGet(args); + var dir="adf/adfas/"; + var file=FileUtil.getDir(dir); + return YancloudUtil.currentTimeMillis(); + } +} +``` + +### @Description +该注解可以修饰`contract`或`function`。 +传入合约及函数的简介,可用于生成说明文档中关于exported函数的介绍。 + +``` +@Description("返回数据条目,无需参数") +export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); +} +``` + +### @Param +该注解可以修饰`function`。 +提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。 +``` +@Param({"offset":0,"count":100}) +export function get(args){ + var offset = args.offset; + var count = args.count; + ... +} +``` +### @MockTemplate +该注解可以修饰`function`。 +提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时,返回按照此格式生成的模拟数据。 + + +####支持的字段类型 +``` +@integer +@string +@boolean +@date +@time +@datatime +/[a-z][A-Z][0-9]/ (正则表达式) +…… +详细格式可以参考http://mockjs.com/examples.html +``` +####注意:模板的格式为{‘result’:模板} +```json +//返回一个1-100之间的整数 +@MockTemplate({'result|1-100':1}) +//返回 +{'result':76} + +//返回一个1-5个数的数组 +@MockTemplate({'result|1-5':[{'value|1-100':1}]}) +//返回 +{"result":[{"value":34},{"value":8},{"value":48},{"value":50},{"value":43}]} + +//返回一个对象包含如下字段 +@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}}) +//返回 +{"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"} + + +//返回元素个数为1-5个之间的一个数组,数组的每个元素都是上述格式的一个对象 +{'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]} +//返回 +[ + {"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"}, + {"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"}, + {"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"} +] +``` +``` +@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}}) +export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); +} +``` +### @Result +该注解可以修饰`function`。 +若没有模拟数据模板,则返回模拟数据时使用该注解的内容 +提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。 +``` +@Result(666) +export function count(args){ + var sql = "select count(*) from data;"; + var conn = getConn(); + var statement = conn.createStatement(); + var resultSet = statement.executeQuery(sql); + var c = {}; + resultSet.next(); + c.count = resultSet.getLong(1); + return JSON.stringify(c); +} +``` +## IO工具类 + +### 概览 + +|IO工具类名称|说明| +|---|---| +| [FileUtil](./YJSAPI.html#fileutil) | 文件操作相关的类 | +| [LedgerUtil](./YJSAPI.html#ledgerutil) | 账本操作相关的类 | +| [HttpUtil](./YJSAPI.html#httputil) | Http接口相关的类 | +| [DOIPUtil](./YJSAPI.html#doiputil) | DoIP相关的类 | +| [MySQLUtil](./YJSAPI.html#mysqlutil) | 连接mysql数据库 | +| [MongoDBUtil](./YJSAPI.html#mongodbutil) | MongoDB连接相关的类 | +| [RocksDBUtil](./YJSAPI.html#rocksdbutil) | RocksDB(基于本地文件的k-v数据库) | +| [BDWareTimeSeriesDBUtil](./YJSAPI.html#BDWareTimeSeriesDBUtil) | 基于本地文件的时间序列数据库 | + + +### FileUtil +可以使用@Permission("File")来引入FileUtil对象。 + +``` +@Permission("File") +contract FileSample { +... +} +``` + +该对象支持以下方法: + +#### copyTo + +可以复制文件和目录。第一个参数是source,第二个参数是destination。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | src | 类型为String | +| 2 | dest | 类型为String | + +##### 使用示例 + +```javascript +var ret = FileUtil.copyTo("./source.txt","./dest.txt"); +``` + +#### getContent + +获取文件的文本内容,当文件不存在时,返回```undefined```。 + +##### 参数 + +| 序号 | 参数 | 说明 | +| --- | --- | --- | +| 1 | path | 类型为String | + +##### 使用示例 + +```javascript +var ret = FileUtil.getContent("./source.txt"); +``` +#### getDir + +获取文件所在的文件夹名,输入参数为字符串。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 类型为String | + +##### 使用示例 +```javascript +var ret = FileUtil.getDir("./parent/src.txt"); +// ret 为 "./parent/"; +``` + +#### getFileName + +获取文件名。输入参数为字符串。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 类型为String | + +##### 使用示例 + +```javascript +var ret = FileUtil.getFileName("./parent/src.txt"); +// ret 为 "src.txt" +``` + + +#### openFileAsPrinter + +以PrintStream的形式打开文件。 +返回结果是```java.io.PrintStream```类型。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 文件名,类型为String | +| 2 | isAppend| 类型为boolean,表示是否往文件末尾添加 | + +##### 使用示例 + +```javascript +var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true); +ret.println("hello"); +ret.close(); +``` + +### LedgerUtil + +可以使用@Permission("Ledger")来引入LedgerUtil对象。 +``` +@Permission("Ledger") +contract LedgerExample{ +... +} +``` + +#### getClient + +获取一个连接客户端,一个参数,为对象类型。 +返回结果为LedgerClient类型,用于后续的查询账本等操作。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | address | 包含ip和端口两个字段 | + +##### 使用示例 + +```javascript +var address = {}; +address.ip = "127.0.0.1"; +address.port = 18091; +var ledgerClient = LedgerUtil.getClient(address); +``` + +#### queryByHash + +根据Hash查询Transaction。 +返回结果为对象,包含from、to、type和data四个字段,均为String类型。 +其中data为按utf-8编码解析字节数组,如果存证时用的不是utf8编码,可能返回乱码。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | client | 通过getClient方法获得的对象 | +| 2 | info | 对象类型,有两个字段ledger和hash,均为字符串类型 | + +##### 使用示例 + +```javascript +// ... ledgerClient = LedgerUtil.getClient(...); +var info = {}; +info.ledger = "bdcontract"; +info.hash = "4d3b75750835092a50085127702669615b602e53"; +var ret = LedgerUtil.queryByHash(ledgerClient,info); +print(ret.from); +print(ret.to); +print(ret.type); +print(ret.data); +``` + +#### sendTransaction + +存证数据。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | client | 通过getClient方法获得的对象 | +| 2 | info | 对象类型,有from\to\data三个字段,均为String类型 | + +##### 使用示例 + +```javascript +// ... ledgerClient = LedgerUtil.getClient(...); +var info = {}; +info.ledger = "bdcontract"; +info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155"; +info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155"; +info.data = "hello world"; +var ret = LedgerUtil.sendTransaction(ledgerClient,info); +//ret为存证的哈希值 +print(ret); +``` + +### HttpUtil + +可以使用@Permission("Http")来引入HttpUtil对象。 +``` +@Permission("Http") +contract HttpExample{ +... +} +``` + +#### createAPIGate + +配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | ip | 字符串类型,ip,端口默认为6161 | + +##### 使用示例 + +```javascript +var ret = HttpUtil.createAPIGate("192.168.4.4"); +ret.get("com.tencent.mm","sendMsg","msg"); +print(ret); +``` + +#### createAPIGate + +配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | ip | 字符串类型,ip| +| 2 | port | 字符串类型,端口 | + +##### 使用示例 + +```javascript +var ret = HttpUtil.createAPIGate("192.168.4.4", "6161"); +ret.get("com.tencent.mm","sendMsg","msg"); +print(ret); +``` + +#### get + +发起Http的get请求。 +返回结果为对象类型,包含response和responseCode两个字段。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | url | 字符串,表示url类型 | + +##### 使用示例 + +```javascript +var ret = HttpUtil.get("https://www.baidu.com"); +print(ret.responseCode); +print(ret.response); +``` + +#### post +发起Http的post请求。 +返回结果为对象类型,包含response和responseCode两个字段。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | args | 对象类型,有url,headers和data三个字段。其中,args.headers为对象类型。| + +##### 使用示例 + +```javascript +var req = {}; +req.url = "https://www.baidu.com"; +req.data = "hello"; +req.header = {}; +req.header.Accept = "application/json"; +req.header["Content-Type"] = "application/json"; +var ret = HttpUtil.post(req); +print(ret.resposeCode); +print(ret.response); +``` + +### DOIPUtil + +可以使用@Permission("DOIP")来引入DOIPUtil对象。 +``` +@Permission("DOIP") +contract DOIPExample{ + ... +} +``` + +#### call +调用一个DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型, 目标DO标识| +| 2 | arg1 | 字符串类型, 输入参数字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.call("86.5000.470/do.hello","inputString"); +``` +#### create +向一个Repository创建一个字符串类型DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型, 目标Repo标识| +| 2 | arg1 | 对象类型,包括doID,doBody字段| + +##### 使用示例 + +```javascript +var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}"); +var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject); +``` +#### delete +从一个Repository中删除DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| +| 2 | arg1 | 字符串类型 目标Repo标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo"); +``` +#### hello +获取目标Repository的DOIP服务信息 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标Repo标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo"); +``` +#### listOperation +获取目标DO支持的DOIP操作 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.listOperation("86.5000.470/do.hello"); +``` +#### register +向LHS注册一个DO,返回分配的标识 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 DO所在Repo标识| +| 2 | arg1 | 字符串类型 DO格式描述字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String"); +``` +#### reregister +修改LHS中DO的注册信息 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| +| 2 | arg1 | 字符串类型 DO所在Repo标识| +| 3 | arg2 | 字符串类型 DO格式描述字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String"); +``` +#### retrieve +获取一个DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 目标DO标识| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.retrieve("86.5000.470/do.hello"); +``` +### test +测试DOIPUtils是否可用 +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | 字符串类型 任意字符串| + +##### 使用示例 + +```javascript +var ret = DOIPUtil.test("hello"); +``` +#### update +更新目标DO + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | arg0 | JS对象,包括doID,doBody字段| + +##### 使用示例 + +```javascript +var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}"); +var ret = DOIPUtil.update(digitalObject); +``` + + + +### MySQLUtil + +可以使用@Permission("MySQL")来引入MySQLUtil对象。 +``` +@Permission("MySQL") +contract MySQLExample{ +... +} +``` + + +#### getConnection + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | URL | 字符串类型,jdbc连接 | +| 2 | usrName | 字符串类型,用户名 | +| 3 | pwd | 字符串类型,密码 | + + +##### 使用示例 + +```javascript +var url = "jdbc:mysql://xx.xx.xx:port/tableName"; +var usrName = "xxx"; +var pwd = "xxx"; +//配置好用户名和密码,url格式为ip或域名+端口,中间以”:”隔开。 +var conn = MySQLUtil.getConnection(url,usrName,pwd); +//获取数据库连接 +var sql = "select * from newele.data"; +//创建查询语句 +var statement = conn.createStatement(); +var resultSet = statement.executeQuery(sql); +var waimailist = []; +//解析查询结果 +var meta = resultSet.getMetaData(); +for (;resultSet.next();){ + var line = {}; + for (var j=1;j<=meta.getColumnCount();j++){ + line[meta.getColumnName(j)] = resultSet.getString(j); + } + waimailist.push(line); +} +``` + +其中,getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此,可以查看: + +以了解如何进行Mysql数据库操作。 + + +### MongoDBUtil + +可以使用@Permission("MongoDB")来引入MongoDBUtil对象。 +``` +@Permission("MongoDB") +contract MongoDBExample{ +... +} +``` + +#### getConnection + + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | URL | 字符串类型 数据库的URL | +| 2 | port | 整数类型 端口号 | +| 3 | dbName | 字符串类型 数据库的名称 | +| 4 | usrName | 字符串类型 数据库的用户名 | +| 5 | pwd | 字符串类型 数据库的密码 | + + +##### 使用示例 + +**注意:port为整型,其他参数为String类型** + +```javascript +var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd); +//获取数据库对象 +var db = client.getDatabase("yancloud"); +var collection = db.getCollection("containers"); +var iter = collection.find().iterator(); +var ret =""; +for (;iter.hasNext();){ + ret+=iter.next().toJson(); + ret+="\n"; +} +``` + +其中,getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此,可以查看: + + +以了解该对象的更多方法和使用方式。 + +### RocksDBUtil + +使用@Permission("RocksDB")来引入RocksDBUtil对象。 + +``` +@Permission("RocksDB") +contract RocksDBSample { +... +} +``` + +#### loadDB + +通过loadDB来加载一个RocksDB数据库。 +加载后,可进行get/delete/put等操作。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | path | 字符串类型 数据库部署的路径 | +| 2 | readOnly | 布尔类型 数据库只读 | + +##### 使用示例 + +``` +@Permission("RocksDB") +@Description("这是个使用RocksDB的参考代码") +contract RocksDBSample{ + function onCreate(){ + Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false"); + } + @Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}") + export function put(arg){ + arg = JSON.parse(arg); + Global.rocksdb.put(arg.key,arg.value); + return "success"; + } + @Description("示例参数: \"abc\"}") + export function get(arg){ + return Global.rocksdb.get(arg); + return "failed"; + } + @Description("示例参数: \"abc\"") + export function deleteKey(arg){ + return Global.rocksdb.delete(arg); + } + @Description("遍历KV库,无需参数") + export function iter(arg){ + var iter = Global.rocksdb.newIterator(); + var obj = undefined; + var ret = { + }; + for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){ + ret[obj.key]=obj.value; + } + return JSON.stringify(ret) + } +} +``` + +### BDWareTimeSeriesDBUtil + +使用示例 + +``` +@Permission("BDWareTimeSeriesDB") +contract BDWareTimeDBExample{ + function onCreate(arg){ + Global.dbutil = BDWareTimeSeriesDBUtil.getConnection(); + } + + export function put(arg){ + //第一个参数为表名,第二个参数为要放的value,时间戳自动打。 + Global.dbutil.put("defaultTable",arg); + return "success"; + } + @Param + export function getCount(arg){ + return Global.dbutil.getCount("defaultTable"); + } + @Param(1617254937373) + export function queryByStartTime(arg){ + var startDate = java.lang.Long.valueOf(arg); + //查询从开始时刻startDate到最新的数据 + var list = Global.dbutil.query("defaultTable",startDate); + var ret=[]; + print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size()); + var i=0; + for (i=0;i"+list.get(i)); + ret.push(list.get(i)); + } + return ret; + } + + @Description("示例参数: {\"offset\":1,\"len\":1}") + @Param({"offset":1,"len":1}) + export function queryByOffset(arg){ + var offsetLen = JSON.parse(arg); + //可配合getCount使用,查询第offset至offset+len条数据 + var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len); + var ret=[]; + print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size()); + var i=0; + for (i=0;i"+list.get(i)); + ret.push(list.get(i)); + } + return ret; + } +} + +``` + + +## 加解密工具类 + + +### SM2 +可以使用@Permission("SM2")来引入SM2Util对象。 + +``` +@Permission("SM2") +contract SM2Sample { +... +} +``` + +#### generateKeyPair +生成公私钥。 + +##### 参数 +无参数。 + +##### 使用示例 + +```javascript +var ret = SM2Util.generateKeyPair(); +print(ret.publicKey); +print(ret.privateKey); +return JSON.stringify(ret); +``` + +#### sign + +签名。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | content | 字符串类型 要进行签名的内容 | +| 2 | keyPair | sm2 | + + +##### 使用示例 + +``` +var keypair = SM2Util.generateKeyPair(); +var ret = SM2Util.sign("Hello",keypair); +print(ret.status); +//如果status是success +print(ret.signature); +//如果status是failed +print(ret.message); +``` + +#### verify + +验签。 + +##### 参数 + +| 序号 | 参数 | 说明 | +|---|---|---| +| 1 | content | 字符串类型 待验签的内容 | +| 2 | signature | 字符串类型 签名 | +| 3 | publicKey | 字符串类型 公钥 | + +##### 使用示例 + +```javascript +var ret = SM2Util.verify("Hello","....签名","...公钥"); +// 验证通过时,result为true,status为success +// 失败时,result为failed,status为failed +print(ret.status); +print(ret.result); +``` + +## 多线程工具类 + +### AsyncUtil + +可以使用@Permission("Async")来引入AsyncUtil对象。 +``` +@Permission("Async") +contract AsyncExample{ + export function longTimeTask(arg){ + var a = { + }; + a.count = 100; + AsyncUtil.postFunction(taskFun,a); + } + function taskFun(arg){ + Global.progress = 0; + for (var i=0;i + +* Number + +* Math + +* Date + +* RegExp + +* Error + +* JSON diff --git a/doc/_sources/markdown_BDWare/YJSInDepth.md.txt b/doc/_sources/markdown_BDWare/YJSInDepth.md.txt new file mode 100644 index 0000000..05068b5 --- /dev/null +++ b/doc/_sources/markdown_BDWare/YJSInDepth.md.txt @@ -0,0 +1,281 @@ +# YJS语法 + +- - - + +## 概述 + +YJS源文件包括任意数量的**import声明**和一个**contract定义**。 + +- - - + +## import声明 + +与JavaScript(ES6)类似,YJS也支持import声明语句,在全局层面,开发者可以使用如下import声明来导入其他文件。 + +``` +import "filename"; +``` + +### 内容 + +import声明语句将包含在“filename”文件中的所有全局符号(单元)导入到当前文件,且全局范围内有效。 + +### 路径 + +**filename**通常用**/**做目录分隔符来表示文件的路径,例如,从同一目录下导入**x.yjs**文件到当前文件,可以使用**import "x.yjs"**语句;从其他目录下导入**x.yjs**使用**import "lib/x.yjs"**语句。 + +- - - + +## Contract定义 + +### 示例 + +以下是一个合约示例,用于JSON处理,此YJS源文件以合约名称命名。 + +``` +contract ScoreAdder{ + //arg = {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"} + export function main(arg){ + //JSON is a build-in object. + var point = JSON.parse(arg); + var s = 0; + print(point[0].score); + print(point.length); + for (var i=0;i + Data from contract: + + + + +``` +示例的资源文件"/html/hello.js"如下: + +```javascript +var queryDataFromContract = function(){ + //第一个参数为函数名,第二个为参数,第三个参数为回调。 + var data = executeCurrentContract("query","abc",function(argg){ + $("#resultText")[0].innerHTML = argg.result; + }); +} +``` + +参考示例: + + + + +### YJS-Python + +TODO + diff --git a/doc/_sources/markdown_BDWare/httpapi.md.txt b/doc/_sources/markdown_BDWare/httpapi.md.txt new file mode 100644 index 0000000..dae8693 --- /dev/null +++ b/doc/_sources/markdown_BDWare/httpapi.md.txt @@ -0,0 +1,594 @@ +``` {.yaml} +type: google.api.Service +config_version: 3 + +http: + rules: + - selector: bdware.bdledger.api.Node.ClientVersion + get: /v0/node/version + - selector: bdware.bdledger.api.Ledger.CreateLedger + post: /v0/ledgers + body: "*" + - selector: bdware.bdledger.api.Ledger.GetLedgers + get: /v0/ledgers + - selector: bdware.bdledger.api.Ledger.SendTransaction + post: /v0/ledgers/{ledger}/transactions + body: "*" + - selector: bdware.bdledger.api.Query.GetBlockByHash + get: /v0/ledgers/{ledger}/block + - selector: bdware.bdledger.api.Query.GetBlocks + post: /v0/ledgers/{ledger}/blocks/query + body: "*" + - selector: bdware.bdledger.api.Query.CountBlocks + post: /v0/ledgers/{ledger}/blocks/count + body: "*" + - selector: bdware.bdledger.api.Query.GetRecentBlocks + get: /v0/ledgers/{ledger}/blocks/recent + - selector: bdware.bdledger.api.Query.GetTransactionByHash + get: /v0/ledgers/{ledger}/transaction + - selector: bdware.bdledger.api.Query.GetTransactionByBlockHashAndIndex + get: /v0/ledgers/{ledger}/block/transaction + - selector: bdware.bdledger.api.Query.GetTransactions + post: /v0/ledgers/{ledger}/transactions/query + body: "*" + - selector: bdware.bdledger.api.Query.CountTransactions + post: /v0/ledgers/{ledger}/transactions/count + body: "*" +``` + +> **Note** +> +> Request/Response data of **bytes** type should/will be encoded with +> [Base64](https://tools.ietf.org/html/rfc4648#section-4). + +> **Note** +> +> When using hash strings in URL, they need to be encoded with +> [encodeURIComponent](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent). + +Request Examples {#_request_examples} +================ + +Node.ClientVersion {#_node_clientversion} +------------------ + +Get BDLedger node version + + GET http://{{IP}}:{{PORT}}/v0/node/version + +**Response.** + +``` {.json} +{ + "version": "dev-210119.a88bf4eb" +} +``` + +Ledger.CreateLedger {#_ledger_createledger} +------------------- + +Create a new ledger + + POST http://{{IP}}:{{PORT}}/v0/ledgers + +**Request body.** + +``` {.json} +{ + "name": "test" +} +``` + +**Response.** + +``` {.json} +{ + "ok": true +} +``` + +Ledger.GetLedgers {#_ledger_getledgers} +----------------- + +Get all ledgers + + GET http://{{IP}}:{{PORT}}/v0/ledgers + +**Response.** + +``` {.json} +{ + "ledgers": [ + "default", + "test" + ] +} +``` + +Ledger.SendTransaction {#_ledger_sendtransaction} +---------------------- + +Send a new transaction + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions + +**Request body.** + +``` {.json} +{ + "transaction": { + "type": 0, + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": 52, + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } +} +``` + +**Response.** + +``` {.json} +{ + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" +} +``` + +Query.GetBlockByHash {#_query_getblockbyhash} +-------------------- + +Get a block identified by its hash + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block?hash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D + +**hash** has to be encoded with +[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) + +**Response.** + +``` {.json} +{ + "block": { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [ + { + "blockHash": "", + "blockTimestamp": "0", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } + ], + "transactionHashes": [ + "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" + ] + } +} +``` + +Query.GetBlocks {#_query_getblocks} +--------------- + +Get blocks in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/query + +``` {.protobuf} +enum IncludeTransactions { + NONE = 0; // Don't include transaction data + HASH = 1; // Include transactions hashes + FULL = 2; // Include full transactions +} +``` + +Requirement: asciimath:\[\"start\_timestamp\"⇐\"end\_timestamp\"\] + +If only **end\_timestamp** is not specified, or +asciimath:\[\"end\_timestamp\"-\"start\_timestamp\"\>\"query.maxDuration\"\], +then **end\_timestamp** will be set to +asciimath:\[\"start\_timestamp\"+\"query.maxDuration\"\]. + +If only **start\_timestamp** is not specified, then **start\_timestamp** +will be set to asciimath:\[\"end\_timestamp\"-\"query.maxDuration\"\]. + +In all cases, **start\_timestamp** will never be earlier than the +genesis block's timestamp, and **end\_timestamp** will never be later +than the current timestamp when the node process the query request. + +**Request body 1.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000, + "include_transactions": 0 +} +``` + +**Response 1.** + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [], + "transactionHashes": [] + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +**Request body 2.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000, + "include_transactions": 1 +} +``` + +**Response 2.** + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [], + "transactionHashes": [ + "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" + ] + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +**Request body 3.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000, + "include_transactions": 2 +} +``` + +**Response 3.** + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [ + { + "blockHash": "", + "blockTimestamp": "0", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } + ], + "transactionHashes": [ + "VQBeA5Ee0Y5hqEileoQuYMHbOSE=" + ] + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +Query.CountBlocks {#_query_countblocks} +----------------- + +Count all blocks in a ledger, or blocks in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/count + +Requirement: asciimath:\[\"start\_timestamp\"⇐\"end\_timestamp\"\] + +If neither **start\_timestamp** nor **end\_timestamp** is specified, +then count all blocks in the specified ledger. + +If only **end\_timestamp** is not specified, then count all blocks with +timestamps later than **start\_timestamp**. + +If only **start\_timestamp** is not specified, then count all blocks +with timestamps earlier than **end\_timestamp**. + +In all cases, **start\_timestamp** will never be earlier than the +genesis block's timestamp, and **end\_timestamp** will never be later +than the current timestamp when the node process the query request. + +**Request body 1.** + +``` {.json} +{} +``` + +**Response 1.** + +``` {.json} +{ + "count": "5", + "startTimestamp": "0", + "endTimestamp": "1611039957" +} +``` + +**Request body 2.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000 +} +``` + +**Response 2.** + +``` {.json} +{ + "count": "1", + "startTimestamp": "1611038000", + "endTimestamp": "1611039000" +} +``` + +Query.GetRecentBlocks {#_query_getrecentblocks} +--------------------- + +Get recent **count** blocks (Only support IncludeTransactions=NONE for +now) + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/recent?count=2 + +**Response.** + +``` {.json} +{ + "blocks": [ + { + "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "3XkwkuMBearq8uavN76Te7Zdpl8=" + ], + "witnesses": [], + "timestamp": "1611038043", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "transactions": [], + "transactionHashes": [] + }, + { + "hash": "rk0DWMaUpRG82yVX+cFhbfhPFdw=", + "creator": "", + "nonce": "0", + "parentHashes": [ + "fLX5pMY8M1qSAGZdKT1rWBkdEMo=", + "3XkwkuMBearq8uavN76Te7Zdpl8=", + "8pZPR74OALIbps5XFb4dL/s0j0M=" + ], + "witnesses": [], + "timestamp": "1610968019", + "size": "0", + "transactionCount": 1, + "transactionsRoot": "LuxttCm/pSHVMOKF0sJExk+DJXc=", + "transactions": [], + "transactionHashes": [] + } + ], + "startTimestamp": "1610968019", + "endTimestamp": "1611038043" +} +``` + +Query.GetTransactionByHash {#_query_gettransactionbyhash} +-------------------------- + +Get a transaction identified by its hash + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/transaction?hash=VQBeA5Ee0Y5hqEileoQuYMHbOSE%3D + +**hash** has to be encoded with +[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) + +**Response.** + +``` {.json} +{ + "transaction": { + "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "blockTimestamp": "1611038043", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } +} +``` + +Query.GetTransactionByBlockHashAndIndex {#_query_gettransactionbyblockhashandindex} +--------------------------------------- + +Get a transaction identified by hash of the block it belongs to and its +index inside the block + + GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block/transaction?blockHash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D&index=0 + +**blockHash** has to be encoded with +[encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) + +**Response.** + +``` {.json} +{ + "transaction": { + "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=", + "blockTimestamp": "1611038043", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } +} +``` + +Query.GetTransactions {#_query_gettransactions} +--------------------- + +Get transactions in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/query + +**start\_timestamp** and **end\_timestamp** follow the same requirements +and rules as in [???](#Query.GetBlocks). + +**Request body.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000 +} +``` + +**Response.** + +``` {.json} +{ + "transactions": [ + { + "blockHash": "", + "blockTimestamp": "0", + "index": 0, + "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=", + "type": "RECORD", + "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=", + "nonce": "0", + "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM=" + } + ], + "startTimestamp": "1611038043", + "endTimestamp": "1611038043" +} +``` + +Query.CountTransactions {#_query_counttransactions} +----------------------- + +Count all transactions in a ledger, or transactions in a timestamp range + + POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/count + +**start\_timestamp** and **end\_timestamp** follow the same requirements +and rules as in [???](#Query.CountBlocks). + +**Request body 1.** + +``` {.json} +{} +``` + +**Response 1.** + +``` {.json} +{ + "count": "4", + "startTimestamp": "0", + "endTimestamp": "1611039957" +} +``` + +**Request body 2.** + +``` {.json} +{ + "start_timestamp": 1611038000, + "end_timestamp": 1611039000 +} +``` + +**Response 2.** + +``` {.json} +{ + "count": "1", + "startTimestamp": "1611038000", + "endTimestamp": "1611039000" +} +``` diff --git a/doc/_static/02-logos/北大数瑞logo-镂空反白-横版.png b/doc/_static/02-logos/北大数瑞logo-镂空反白-横版.png new file mode 100644 index 0000000..ab47958 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo-镂空反白-横版.png differ diff --git a/doc/_static/02-logos/北大数瑞logo-镂空反白-横版@2x.png b/doc/_static/02-logos/北大数瑞logo-镂空反白-横版@2x.png new file mode 100644 index 0000000..1e47d6f Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo-镂空反白-横版@2x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo-镂空反白-横版@3x.png b/doc/_static/02-logos/北大数瑞logo-镂空反白-横版@3x.png new file mode 100644 index 0000000..4678a9a Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo-镂空反白-横版@3x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版.png b/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版.png new file mode 100644 index 0000000..3b8e931 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版.png differ diff --git a/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版@2x.png b/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版@2x.png new file mode 100644 index 0000000..1fe4458 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版@2x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版@3x.png b/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版@3x.png new file mode 100644 index 0000000..65e3c1a Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo-镂空反白-竖版@3x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo深色背景-横版.png b/doc/_static/02-logos/北大数瑞logo深色背景-横版.png new file mode 100644 index 0000000..6657c8e Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo深色背景-横版.png differ diff --git a/doc/_static/02-logos/北大数瑞logo深色背景-横版@2x.png b/doc/_static/02-logos/北大数瑞logo深色背景-横版@2x.png new file mode 100644 index 0000000..8f47df3 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo深色背景-横版@2x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo深色背景-横版@3x.png b/doc/_static/02-logos/北大数瑞logo深色背景-横版@3x.png new file mode 100644 index 0000000..a64dac0 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo深色背景-横版@3x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo竖版-深色背景.png b/doc/_static/02-logos/北大数瑞logo竖版-深色背景.png new file mode 100644 index 0000000..81e793a Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo竖版-深色背景.png differ diff --git a/doc/_static/02-logos/北大数瑞logo竖版-深色背景@2x.png b/doc/_static/02-logos/北大数瑞logo竖版-深色背景@2x.png new file mode 100644 index 0000000..7a6ae50 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo竖版-深色背景@2x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo竖版-深色背景@3x.png b/doc/_static/02-logos/北大数瑞logo竖版-深色背景@3x.png new file mode 100644 index 0000000..1a4b696 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo竖版-深色背景@3x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo竖版.png b/doc/_static/02-logos/北大数瑞logo竖版.png new file mode 100644 index 0000000..062258b Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo竖版.png differ diff --git a/doc/_static/02-logos/北大数瑞logo竖版@2x.png b/doc/_static/02-logos/北大数瑞logo竖版@2x.png new file mode 100644 index 0000000..32a5e10 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo竖版@2x.png differ diff --git a/doc/_static/02-logos/北大数瑞logo竖版@3x.png b/doc/_static/02-logos/北大数瑞logo竖版@3x.png new file mode 100644 index 0000000..ea02f33 Binary files /dev/null and b/doc/_static/02-logos/北大数瑞logo竖版@3x.png differ diff --git a/doc/_static/02-logos/北大数睿logo横版.png b/doc/_static/02-logos/北大数睿logo横版.png new file mode 100644 index 0000000..b72352b Binary files /dev/null and b/doc/_static/02-logos/北大数睿logo横版.png differ diff --git a/doc/_static/02-logos/北大数睿logo横版@2x.png b/doc/_static/02-logos/北大数睿logo横版@2x.png new file mode 100644 index 0000000..d022b52 Binary files /dev/null and b/doc/_static/02-logos/北大数睿logo横版@2x.png differ diff --git a/doc/_static/02-logos/北大数睿logo横版@3x.png b/doc/_static/02-logos/北大数睿logo横版@3x.png new file mode 100644 index 0000000..70c0436 Binary files /dev/null and b/doc/_static/02-logos/北大数睿logo横版@3x.png differ diff --git a/doc/_static/BDWareConfigTool.zip b/doc/_static/BDWareConfigTool.zip new file mode 100644 index 0000000..b6464f4 Binary files /dev/null and b/doc/_static/BDWareConfigTool.zip differ diff --git a/doc/_static/BDWareJavaClient.zip b/doc/_static/BDWareJavaClient.zip new file mode 100644 index 0000000..e2d7c77 Binary files /dev/null and b/doc/_static/BDWareJavaClient.zip differ diff --git a/doc/_static/basic.css b/doc/_static/basic.css new file mode 100644 index 0000000..be19270 --- /dev/null +++ b/doc/_static/basic.css @@ -0,0 +1,856 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/doc/_static/css/badge_only.css b/doc/_static/css/badge_only.css new file mode 100644 index 0000000..e380325 --- /dev/null +++ b/doc/_static/css/badge_only.css @@ -0,0 +1 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/doc/_static/css/fonts/Roboto-Slab-Bold.woff b/doc/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/doc/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 b/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/doc/_static/css/fonts/Roboto-Slab-Regular.woff b/doc/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/doc/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 b/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/doc/_static/css/fonts/fontawesome-webfont.eot b/doc/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/doc/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/doc/_static/css/fonts/fontawesome-webfont.svg b/doc/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/doc/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/_static/css/fonts/fontawesome-webfont.ttf b/doc/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/doc/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/doc/_static/css/fonts/fontawesome-webfont.woff b/doc/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/doc/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/doc/_static/css/fonts/fontawesome-webfont.woff2 b/doc/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/doc/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/doc/_static/css/fonts/lato-bold-italic.woff b/doc/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/doc/_static/css/fonts/lato-bold-italic.woff differ diff --git a/doc/_static/css/fonts/lato-bold-italic.woff2 b/doc/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/doc/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/doc/_static/css/fonts/lato-bold.woff b/doc/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/doc/_static/css/fonts/lato-bold.woff differ diff --git a/doc/_static/css/fonts/lato-bold.woff2 b/doc/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/doc/_static/css/fonts/lato-bold.woff2 differ diff --git a/doc/_static/css/fonts/lato-normal-italic.woff b/doc/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/doc/_static/css/fonts/lato-normal-italic.woff differ diff --git a/doc/_static/css/fonts/lato-normal-italic.woff2 b/doc/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/doc/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/doc/_static/css/fonts/lato-normal.woff b/doc/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/doc/_static/css/fonts/lato-normal.woff differ diff --git a/doc/_static/css/fonts/lato-normal.woff2 b/doc/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/doc/_static/css/fonts/lato-normal.woff2 differ diff --git a/doc/_static/css/theme.css b/doc/_static/css/theme.css new file mode 100644 index 0000000..8cd4f10 --- /dev/null +++ b/doc/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"\f0c1";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:" : "}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/doc/_static/doctools.js b/doc/_static/doctools.js new file mode 100644 index 0000000..61ac9d2 --- /dev/null +++ b/doc/_static/doctools.js @@ -0,0 +1,321 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/doc/_static/documentation_options.js b/doc/_static/documentation_options.js new file mode 100644 index 0000000..fd791fc --- /dev/null +++ b/doc/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: 'V1.0', + LANGUAGE: 'zh_CN', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/doc/_static/favicon.ico b/doc/_static/favicon.ico new file mode 100644 index 0000000..56aa953 Binary files /dev/null and b/doc/_static/favicon.ico differ diff --git a/doc/_static/file.png b/doc/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/doc/_static/file.png differ diff --git a/doc/_static/imgs/analysis.png b/doc/_static/imgs/analysis.png new file mode 100644 index 0000000..88ac1d3 Binary files /dev/null and b/doc/_static/imgs/analysis.png differ diff --git a/doc/_static/imgs/analysis1.png b/doc/_static/imgs/analysis1.png new file mode 100644 index 0000000..4e5774d Binary files /dev/null and b/doc/_static/imgs/analysis1.png differ diff --git a/doc/_static/imgs/analysis2.png b/doc/_static/imgs/analysis2.png new file mode 100644 index 0000000..4b0ab0d Binary files /dev/null and b/doc/_static/imgs/analysis2.png differ diff --git a/doc/_static/imgs/analysis3.png b/doc/_static/imgs/analysis3.png new file mode 100644 index 0000000..a1bb383 Binary files /dev/null and b/doc/_static/imgs/analysis3.png differ diff --git a/doc/_static/imgs/analysisExecuteResult.png b/doc/_static/imgs/analysisExecuteResult.png new file mode 100644 index 0000000..80b52cd Binary files /dev/null and b/doc/_static/imgs/analysisExecuteResult.png differ diff --git a/doc/_static/imgs/authList.jpg b/doc/_static/imgs/authList.jpg new file mode 100644 index 0000000..741d070 Binary files /dev/null and b/doc/_static/imgs/authList.jpg differ diff --git a/doc/_static/imgs/authMan.jpg b/doc/_static/imgs/authMan.jpg new file mode 100644 index 0000000..df1041e Binary files /dev/null and b/doc/_static/imgs/authMan.jpg differ diff --git a/doc/_static/imgs/authMana.jpg b/doc/_static/imgs/authMana.jpg new file mode 100644 index 0000000..1fb6be4 Binary files /dev/null and b/doc/_static/imgs/authMana.jpg differ diff --git a/doc/_static/imgs/authNodeManager.jpg b/doc/_static/imgs/authNodeManager.jpg new file mode 100644 index 0000000..ce63e83 Binary files /dev/null and b/doc/_static/imgs/authNodeManager.jpg differ diff --git a/doc/_static/imgs/authorizationOrNot.jpg b/doc/_static/imgs/authorizationOrNot.jpg new file mode 100644 index 0000000..7ca81fc Binary files /dev/null and b/doc/_static/imgs/authorizationOrNot.jpg differ diff --git a/doc/_static/imgs/bash-api.png b/doc/_static/imgs/bash-api.png new file mode 100644 index 0000000..3d6cc3b Binary files /dev/null and b/doc/_static/imgs/bash-api.png differ diff --git a/doc/_static/imgs/centerManager.jpg b/doc/_static/imgs/centerManager.jpg new file mode 100644 index 0000000..eabae32 Binary files /dev/null and b/doc/_static/imgs/centerManager.jpg differ diff --git a/doc/_static/imgs/centerNodeList.png b/doc/_static/imgs/centerNodeList.png new file mode 100644 index 0000000..e8668f9 Binary files /dev/null and b/doc/_static/imgs/centerNodeList.png differ diff --git a/doc/_static/imgs/centerNodePage.png b/doc/_static/imgs/centerNodePage.png new file mode 100644 index 0000000..07e78d8 Binary files /dev/null and b/doc/_static/imgs/centerNodePage.png differ diff --git a/doc/_static/imgs/centerNodePreview.png b/doc/_static/imgs/centerNodePreview.png new file mode 100644 index 0000000..111c9ea Binary files /dev/null and b/doc/_static/imgs/centerNodePreview.png differ diff --git a/doc/_static/imgs/centerNodeUnitCreate.png b/doc/_static/imgs/centerNodeUnitCreate.png new file mode 100644 index 0000000..314f71e Binary files /dev/null and b/doc/_static/imgs/centerNodeUnitCreate.png differ diff --git a/doc/_static/imgs/centerNodeUnits.png b/doc/_static/imgs/centerNodeUnits.png new file mode 100644 index 0000000..fa7e86d Binary files /dev/null and b/doc/_static/imgs/centerNodeUnits.png differ diff --git a/doc/_static/imgs/checkUser.jpg b/doc/_static/imgs/checkUser.jpg new file mode 100644 index 0000000..9c94318 Binary files /dev/null and b/doc/_static/imgs/checkUser.jpg differ diff --git a/doc/_static/imgs/checkUser.png b/doc/_static/imgs/checkUser.png new file mode 100644 index 0000000..2282d10 Binary files /dev/null and b/doc/_static/imgs/checkUser.png differ diff --git a/doc/_static/imgs/chooseInstance.png b/doc/_static/imgs/chooseInstance.png new file mode 100644 index 0000000..dd58914 Binary files /dev/null and b/doc/_static/imgs/chooseInstance.png differ diff --git a/doc/_static/imgs/closePermission.png b/doc/_static/imgs/closePermission.png new file mode 100644 index 0000000..2df7c24 Binary files /dev/null and b/doc/_static/imgs/closePermission.png differ diff --git a/doc/_static/imgs/codeManage1-1.png b/doc/_static/imgs/codeManage1-1.png new file mode 100644 index 0000000..2af24cb Binary files /dev/null and b/doc/_static/imgs/codeManage1-1.png differ diff --git a/doc/_static/imgs/codeManage1-2.png b/doc/_static/imgs/codeManage1-2.png new file mode 100644 index 0000000..57d5727 Binary files /dev/null and b/doc/_static/imgs/codeManage1-2.png differ diff --git a/doc/_static/imgs/codeManage1.png b/doc/_static/imgs/codeManage1.png new file mode 100644 index 0000000..aff2b9a Binary files /dev/null and b/doc/_static/imgs/codeManage1.png differ diff --git a/doc/_static/imgs/codeManage2.png b/doc/_static/imgs/codeManage2.png new file mode 100644 index 0000000..dd4fad0 Binary files /dev/null and b/doc/_static/imgs/codeManage2.png differ diff --git a/doc/_static/imgs/codeManage3.png b/doc/_static/imgs/codeManage3.png new file mode 100644 index 0000000..7676d76 Binary files /dev/null and b/doc/_static/imgs/codeManage3.png differ diff --git a/doc/_static/imgs/codeManage4.png b/doc/_static/imgs/codeManage4.png new file mode 100644 index 0000000..ad0606d Binary files /dev/null and b/doc/_static/imgs/codeManage4.png differ diff --git a/doc/_static/imgs/codeManage5.png b/doc/_static/imgs/codeManage5.png new file mode 100644 index 0000000..8b9c382 Binary files /dev/null and b/doc/_static/imgs/codeManage5.png differ diff --git a/doc/_static/imgs/codeManage6.png b/doc/_static/imgs/codeManage6.png new file mode 100644 index 0000000..03ade62 Binary files /dev/null and b/doc/_static/imgs/codeManage6.png differ diff --git a/doc/_static/imgs/codeManage7.png b/doc/_static/imgs/codeManage7.png new file mode 100644 index 0000000..4a48550 Binary files /dev/null and b/doc/_static/imgs/codeManage7.png differ diff --git a/doc/_static/imgs/codeManage8.png b/doc/_static/imgs/codeManage8.png new file mode 100644 index 0000000..57ad15e Binary files /dev/null and b/doc/_static/imgs/codeManage8.png differ diff --git a/doc/_static/imgs/codeManageMenu.png b/doc/_static/imgs/codeManageMenu.png new file mode 100644 index 0000000..ddaf7d1 Binary files /dev/null and b/doc/_static/imgs/codeManageMenu.png differ diff --git a/doc/_static/imgs/config.png b/doc/_static/imgs/config.png new file mode 100644 index 0000000..111d0ca Binary files /dev/null and b/doc/_static/imgs/config.png differ diff --git a/doc/_static/imgs/contract.jpg b/doc/_static/imgs/contract.jpg new file mode 100644 index 0000000..a165388 Binary files /dev/null and b/doc/_static/imgs/contract.jpg differ diff --git a/doc/_static/imgs/contractList.jpg b/doc/_static/imgs/contractList.jpg new file mode 100644 index 0000000..6cf8be2 Binary files /dev/null and b/doc/_static/imgs/contractList.jpg differ diff --git a/doc/_static/imgs/contractLog.jpg b/doc/_static/imgs/contractLog.jpg new file mode 100644 index 0000000..de245e6 Binary files /dev/null and b/doc/_static/imgs/contractLog.jpg differ diff --git a/doc/_static/imgs/contractMode.png b/doc/_static/imgs/contractMode.png new file mode 100644 index 0000000..b32397b Binary files /dev/null and b/doc/_static/imgs/contractMode.png differ diff --git a/doc/_static/imgs/contracteveryLog.jpg b/doc/_static/imgs/contracteveryLog.jpg new file mode 100644 index 0000000..65d683b Binary files /dev/null and b/doc/_static/imgs/contracteveryLog.jpg differ diff --git a/doc/_static/imgs/dashboard.jpg b/doc/_static/imgs/dashboard.jpg new file mode 100644 index 0000000..23c862b Binary files /dev/null and b/doc/_static/imgs/dashboard.jpg differ diff --git a/doc/_static/imgs/deploytopology.png b/doc/_static/imgs/deploytopology.png new file mode 100644 index 0000000..c326fac Binary files /dev/null and b/doc/_static/imgs/deploytopology.png differ diff --git a/doc/_static/imgs/dirstructure.png b/doc/_static/imgs/dirstructure.png new file mode 100644 index 0000000..e2c6098 Binary files /dev/null and b/doc/_static/imgs/dirstructure.png differ diff --git a/doc/_static/imgs/docs.png b/doc/_static/imgs/docs.png new file mode 100644 index 0000000..828ecf9 Binary files /dev/null and b/doc/_static/imgs/docs.png differ diff --git a/doc/_static/imgs/everyLog.jpg b/doc/_static/imgs/everyLog.jpg new file mode 100644 index 0000000..fcc7c56 Binary files /dev/null and b/doc/_static/imgs/everyLog.jpg differ diff --git a/doc/_static/imgs/executeResult.png b/doc/_static/imgs/executeResult.png new file mode 100644 index 0000000..21b9e51 Binary files /dev/null and b/doc/_static/imgs/executeResult.png differ diff --git a/doc/_static/imgs/favicon.ico b/doc/_static/imgs/favicon.ico new file mode 100644 index 0000000..56aa953 Binary files /dev/null and b/doc/_static/imgs/favicon.ico differ diff --git a/doc/_static/imgs/fork1.png b/doc/_static/imgs/fork1.png new file mode 100644 index 0000000..931a43b Binary files /dev/null and b/doc/_static/imgs/fork1.png differ diff --git a/doc/_static/imgs/fork2.png b/doc/_static/imgs/fork2.png new file mode 100644 index 0000000..6f0d531 Binary files /dev/null and b/doc/_static/imgs/fork2.png differ diff --git a/doc/_static/imgs/fork3.png b/doc/_static/imgs/fork3.png new file mode 100644 index 0000000..81702dc Binary files /dev/null and b/doc/_static/imgs/fork3.png differ diff --git a/doc/_static/imgs/genReadme.png b/doc/_static/imgs/genReadme.png new file mode 100644 index 0000000..dd3347a Binary files /dev/null and b/doc/_static/imgs/genReadme.png differ diff --git a/doc/_static/imgs/http-api.png b/doc/_static/imgs/http-api.png new file mode 100644 index 0000000..be7b2f9 Binary files /dev/null and b/doc/_static/imgs/http-api.png differ diff --git a/doc/_static/imgs/ide_screenshots1.1.png b/doc/_static/imgs/ide_screenshots1.1.png new file mode 100644 index 0000000..7588fb1 Binary files /dev/null and b/doc/_static/imgs/ide_screenshots1.1.png differ diff --git a/doc/_static/imgs/ide_screenshots2.2.png b/doc/_static/imgs/ide_screenshots2.2.png new file mode 100644 index 0000000..a4a766d Binary files /dev/null and b/doc/_static/imgs/ide_screenshots2.2.png differ diff --git a/doc/_static/imgs/index.png b/doc/_static/imgs/index.png new file mode 100644 index 0000000..5cc7516 Binary files /dev/null and b/doc/_static/imgs/index.png differ diff --git a/doc/_static/imgs/intanceExecute.png b/doc/_static/imgs/intanceExecute.png new file mode 100644 index 0000000..bd66b1f Binary files /dev/null and b/doc/_static/imgs/intanceExecute.png differ diff --git a/doc/_static/imgs/licence.jpg b/doc/_static/imgs/licence.jpg new file mode 100644 index 0000000..22010d6 Binary files /dev/null and b/doc/_static/imgs/licence.jpg differ diff --git a/doc/_static/imgs/licence.png b/doc/_static/imgs/licence.png new file mode 100644 index 0000000..cca1c2d Binary files /dev/null and b/doc/_static/imgs/licence.png differ diff --git a/doc/_static/imgs/log.jpg b/doc/_static/imgs/log.jpg new file mode 100644 index 0000000..075d0b0 Binary files /dev/null and b/doc/_static/imgs/log.jpg differ diff --git a/doc/_static/imgs/log1.png b/doc/_static/imgs/log1.png new file mode 100644 index 0000000..04e05a0 Binary files /dev/null and b/doc/_static/imgs/log1.png differ diff --git a/doc/_static/imgs/log2.png b/doc/_static/imgs/log2.png new file mode 100644 index 0000000..33773f7 Binary files /dev/null and b/doc/_static/imgs/log2.png differ diff --git a/doc/_static/imgs/log3.png b/doc/_static/imgs/log3.png new file mode 100644 index 0000000..a2bde90 Binary files /dev/null and b/doc/_static/imgs/log3.png differ diff --git a/doc/_static/imgs/logMenu.png b/doc/_static/imgs/logMenu.png new file mode 100644 index 0000000..9fd8fc5 Binary files /dev/null and b/doc/_static/imgs/logMenu.png differ diff --git a/doc/_static/imgs/logo.png b/doc/_static/imgs/logo.png new file mode 100644 index 0000000..79d515e Binary files /dev/null and b/doc/_static/imgs/logo.png differ diff --git a/doc/_static/imgs/logo2.png b/doc/_static/imgs/logo2.png new file mode 100644 index 0000000..ab47958 Binary files /dev/null and b/doc/_static/imgs/logo2.png differ diff --git a/doc/_static/imgs/memoryDump.png b/doc/_static/imgs/memoryDump.png new file mode 100644 index 0000000..44356a2 Binary files /dev/null and b/doc/_static/imgs/memoryDump.png differ diff --git a/doc/_static/imgs/node.jpg b/doc/_static/imgs/node.jpg new file mode 100644 index 0000000..9827b89 Binary files /dev/null and b/doc/_static/imgs/node.jpg differ diff --git a/doc/_static/imgs/nodeConfig.png b/doc/_static/imgs/nodeConfig.png new file mode 100644 index 0000000..1954dc2 Binary files /dev/null and b/doc/_static/imgs/nodeConfig.png differ diff --git a/doc/_static/imgs/nodeConfigChange.png b/doc/_static/imgs/nodeConfigChange.png new file mode 100644 index 0000000..1f771a9 Binary files /dev/null and b/doc/_static/imgs/nodeConfigChange.png differ diff --git a/doc/_static/imgs/nodeInfo.jpg b/doc/_static/imgs/nodeInfo.jpg new file mode 100644 index 0000000..2282d10 Binary files /dev/null and b/doc/_static/imgs/nodeInfo.jpg differ diff --git a/doc/_static/imgs/nodeInstancesList.png b/doc/_static/imgs/nodeInstancesList.png new file mode 100644 index 0000000..e7e3fd1 Binary files /dev/null and b/doc/_static/imgs/nodeInstancesList.png differ diff --git a/doc/_static/imgs/nodeInstancesPage.png b/doc/_static/imgs/nodeInstancesPage.png new file mode 100644 index 0000000..35e8478 Binary files /dev/null and b/doc/_static/imgs/nodeInstancesPage.png differ diff --git a/doc/_static/imgs/nodeLicence.png b/doc/_static/imgs/nodeLicence.png new file mode 100644 index 0000000..940bab1 Binary files /dev/null and b/doc/_static/imgs/nodeLicence.png differ diff --git a/doc/_static/imgs/nodeUnits.png b/doc/_static/imgs/nodeUnits.png new file mode 100644 index 0000000..502d271 Binary files /dev/null and b/doc/_static/imgs/nodeUnits.png differ diff --git a/doc/_static/imgs/nodeUserManager.jpg b/doc/_static/imgs/nodeUserManager.jpg new file mode 100644 index 0000000..24a4612 Binary files /dev/null and b/doc/_static/imgs/nodeUserManager.jpg differ diff --git a/doc/_static/imgs/nullPermission.png b/doc/_static/imgs/nullPermission.png new file mode 100644 index 0000000..7573bdb Binary files /dev/null and b/doc/_static/imgs/nullPermission.png differ diff --git a/doc/_static/imgs/opList.jpg b/doc/_static/imgs/opList.jpg new file mode 100644 index 0000000..52098d9 Binary files /dev/null and b/doc/_static/imgs/opList.jpg differ diff --git a/doc/_static/imgs/operator.jpg b/doc/_static/imgs/operator.jpg new file mode 100644 index 0000000..9417d67 Binary files /dev/null and b/doc/_static/imgs/operator.jpg differ diff --git a/doc/_static/imgs/permissionShow.png b/doc/_static/imgs/permissionShow.png new file mode 100644 index 0000000..34223df Binary files /dev/null and b/doc/_static/imgs/permissionShow.png differ diff --git a/doc/_static/imgs/pic1.png b/doc/_static/imgs/pic1.png new file mode 100644 index 0000000..804b056 Binary files /dev/null and b/doc/_static/imgs/pic1.png differ diff --git a/doc/_static/imgs/pic2.png b/doc/_static/imgs/pic2.png new file mode 100644 index 0000000..f4b8520 Binary files /dev/null and b/doc/_static/imgs/pic2.png differ diff --git a/doc/_static/imgs/plicence.jpg b/doc/_static/imgs/plicence.jpg new file mode 100644 index 0000000..5250e6d Binary files /dev/null and b/doc/_static/imgs/plicence.jpg differ diff --git a/doc/_static/imgs/projectdir.png b/doc/_static/imgs/projectdir.png new file mode 100644 index 0000000..4298746 Binary files /dev/null and b/doc/_static/imgs/projectdir.png differ diff --git a/doc/_static/imgs/roleAuth.jpg b/doc/_static/imgs/roleAuth.jpg new file mode 100644 index 0000000..b00e6ce Binary files /dev/null and b/doc/_static/imgs/roleAuth.jpg differ diff --git a/doc/_static/imgs/set.jpg b/doc/_static/imgs/set.jpg new file mode 100644 index 0000000..56ddd88 Binary files /dev/null and b/doc/_static/imgs/set.jpg differ diff --git a/doc/_static/imgs/shortcut.png b/doc/_static/imgs/shortcut.png new file mode 100644 index 0000000..bd940ee Binary files /dev/null and b/doc/_static/imgs/shortcut.png differ diff --git a/doc/_static/imgs/shortcut3.png b/doc/_static/imgs/shortcut3.png new file mode 100644 index 0000000..e000d9b Binary files /dev/null and b/doc/_static/imgs/shortcut3.png differ diff --git a/doc/_static/imgs/timeTravel.png b/doc/_static/imgs/timeTravel.png new file mode 100644 index 0000000..a9317a8 Binary files /dev/null and b/doc/_static/imgs/timeTravel.png differ diff --git a/doc/_static/imgs/timetravel2.png b/doc/_static/imgs/timetravel2.png new file mode 100644 index 0000000..495ff0a Binary files /dev/null and b/doc/_static/imgs/timetravel2.png differ diff --git a/doc/_static/imgs/timetravel3.png b/doc/_static/imgs/timetravel3.png new file mode 100644 index 0000000..c227866 Binary files /dev/null and b/doc/_static/imgs/timetravel3.png differ diff --git a/doc/_static/imgs/timetravel4.png b/doc/_static/imgs/timetravel4.png new file mode 100644 index 0000000..d3347cc Binary files /dev/null and b/doc/_static/imgs/timetravel4.png differ diff --git a/doc/_static/imgs/trustful.png b/doc/_static/imgs/trustful.png new file mode 100644 index 0000000..f09d767 Binary files /dev/null and b/doc/_static/imgs/trustful.png differ diff --git a/doc/_static/imgs/updatePermission.png b/doc/_static/imgs/updatePermission.png new file mode 100644 index 0000000..7998271 Binary files /dev/null and b/doc/_static/imgs/updatePermission.png differ diff --git a/doc/_static/imgs/userActive.jpg b/doc/_static/imgs/userActive.jpg new file mode 100644 index 0000000..0ea95ac Binary files /dev/null and b/doc/_static/imgs/userActive.jpg differ diff --git a/doc/_static/imgs/userAll.jpg b/doc/_static/imgs/userAll.jpg new file mode 100644 index 0000000..ef58c6d Binary files /dev/null and b/doc/_static/imgs/userAll.jpg differ diff --git a/doc/_static/imgs/userApplyGraph.jpg b/doc/_static/imgs/userApplyGraph.jpg new file mode 100644 index 0000000..343e946 Binary files /dev/null and b/doc/_static/imgs/userApplyGraph.jpg differ diff --git a/doc/_static/imgs/userList.jpg b/doc/_static/imgs/userList.jpg new file mode 100644 index 0000000..927e5fd Binary files /dev/null and b/doc/_static/imgs/userList.jpg differ diff --git a/doc/_static/imgs/userManager.jpg b/doc/_static/imgs/userManager.jpg new file mode 100644 index 0000000..05903ec Binary files /dev/null and b/doc/_static/imgs/userManager.jpg differ diff --git a/doc/_static/imgs/websocket-api.png b/doc/_static/imgs/websocket-api.png new file mode 100644 index 0000000..9e38a75 Binary files /dev/null and b/doc/_static/imgs/websocket-api.png differ diff --git a/doc/_static/jquery-3.5.1.js b/doc/_static/jquery-3.5.1.js new file mode 100644 index 0000000..5093733 --- /dev/null +++ b/doc/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 索引
  • + + +
  • + + + +
  • + +
+ + +
+
+
+
+ + +

索引

+ +
+ +
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..92439fe --- /dev/null +++ b/doc/index.html @@ -0,0 +1,422 @@ + + + + + + + + + + 北大数瑞大数据区块链 文档 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

北大数瑞大数据区块链 文档

+
+

目录

+ +
+
+ + +
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown/ContractAPI.html b/doc/markdown/ContractAPI.html new file mode 100644 index 0000000..2ab84f8 --- /dev/null +++ b/doc/markdown/ContractAPI.html @@ -0,0 +1,5790 @@ + + + + + + + + + + BDContract SDK — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract SDK

+

除使用可视化的智能合约在线IDE外,用户还可使用WebSocket接口、Http接口、Bash接口来启动和运行合约.

+
+
+

WebSocketSDK下载与安装

+

合约SDK提供javascript版本与java版本的客户端。

+

java客户端的下载链接为:java sourcejar +可参考java_source下的README.md及测试用例。

+

javascript的下载链接为:js SDK +内置的SM2加密库链接:sm2 SDK

+
+

建立连接

+

建立与节点服务器之间的WebSocket连接.

+
+

参数

+ + + + + + + + + + + + + + + + + +
字段
url建立WebSocket的服务器URL. 使用http协议时, 前缀为ws://, 如"ws://localhost:1717/SCIDE/SCExecutor"; 使用https协议时, 前缀为wss://
msgHandler收到服务器WebSocket回复后的回调函数, 用户可自行编写, 也可参考下面提供的示例
+
+

请求示例

+
var url = "ws://127.0.0.1:1717/SCIDE/SCExecutor";//与Slave节点建立连接
+//var url = "ws://127.0.0.1:1718/NodeCenterWS";//与Manager节点建立连接
+var msgHandler = function(m){
+  console.log("recmsg:");
+  console.log(m);
+};
+var onOpenHandler=undefined;
+wssocket = createWssocket(url,onOpenHandler,msgHandler);
+
+
+
+
+

返回结果示例

+
{
+  receiveSeg: [Function (anonymous)],
+  isSending: false,
+  sendList: [],
+  monitor: [Function (anonymous)],
+  send: [Function (anonymous)],
+  sendNextSegment: [Function (anonymous)],
+  isOpen: [Function (anonymous)]
+}
+
+
+
+
+
+

ping

+

ping服务器测试

+
+

参数

+ + + + + + + + + + + + + +
字段
actionping
+
+

请求示例

+
var request = {};
+request.action = "ping";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+

返回结果示例

+
{
+    "action":"pong"
+}
+
+
+
+
+
+

登录

+

使用Websocket接口调用需要权限的接口时,不论是连接CenterPortal还是NodePortal必须先登录。 +登录的流程有3步:

+
    +
  • 客户端向服务端建立连接,连接建立完成后发送{“action”:”getSessionID”}(可在onOpenHandler中实现)

  • +
  • 服务端收到请求后,会向客户端返回类似{“action”:”onGetSessionID”,”session”:”-4959947809200104526_session”}的结果

  • +
  • 客户端收到onGetSessionID后,会使用本地的公私钥对sessionID进行签名,并调用login接口

  • +
  • 服务端会返回onLogin的结果,data字段返回的是该公钥对应的角色。

  • +
+
+
+
+
+

用户角色划分

+
+

合约节点的角色划分

+

在合约节点(NodePortal.html)中分为NodeManager/ContractProvider/ContractInstanceManager/ContractUser四类角色。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
角色说明
NodeManager该节点的管理者,拥有用户管理、节点配置等权限
ContractProvider拥有编辑合约、开发合约代码、运行调试等权限
ContractInstanceManager拥有启、停合约实例、配置合约实例IO等权限
ContractUser拥有查看合约实例列表、调用合约等权限
Anonymous匿名用户,可以调用合约,可以申请成为ContractProvider/InstanceManager等角色
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
接口说明角色
changeDumpPeriod设置备份周期ContractInstanceManager;
createLedger创建账本ContractInstanceManager;
dumpContract手动备份ContractInstanceManager;
deleteMemoryFile删除镜像ContractInstanceManager;
forkContract迁移合约ContractInstanceManager;
getDumpPeriod获取备份周期ContractInstanceManager;
killAllContract停止全部实例ContractInstanceManager;
killContractProcess停止某一实例ContractInstanceManager;
listMemoryFiles列取某一实例的镜像ContractInstanceManager;
loadMemory加载镜像ContractInstanceManager;
queryContractInstanceDOI查询合约实例信息ContractInstanceManager;
rebuildHashIndexContractInstanceManager;
setPermissionContractProvider;ContractInstanceManager;
startContract启动合约ContractInstanceManager;
startContractBatched废弃ContractInstanceManager;
startContractByYPK启动合约ContractInstanceManager;
startContractInTempZips废弃ContractInstanceManager;
startContractP2PTrustfully启动合约(集群模式)ContractInstanceManager;
updateContractContractInstanceManager;
connectTo连接合约实例输出流ContractInstanceManager;ContractUser;
countContractLogGroupByActionContractInstanceManager;ContractUser;
countContractLogGroupByCategoryContractInstanceManager;ContractUser;
getLastLog查询日志ContractInstanceManager;ContractUser;
getLog查询日志ContractInstanceManager;ContractUser;
getLogSize查询日志ContractInstanceManager;ContractUser;
listAllContractProcessContractInstanceManager;ContractUser;
listContractProcess查询合约实例列表ContractInstanceManager;ContractUser;
listLeakContractProcessContractInstanceManager;ContractUser;
queryContractLogByDateContractInstanceManager;ContractUser;
queryContractLogByKeyContractInstanceManager;ContractUser;
queryContractLogByOffsetContractInstanceManager;ContractUser;
queryContractLogDetailContractInstanceManager;ContractUser;
queryContractLogSizeContractInstanceManager;ContractUser;
queryNodeLogByDateContractInstanceManager;ContractUser;
queryNodeLogByOffsetContractInstanceManager;ContractUser;
queryNodeLogSizeContractInstanceManager;ContractUser;
rebuildContractLogIndexContractInstanceManager;ContractUser;
rebuildNodeLogIndexContractInstanceManager;ContractUser;
changePublicContractProvider;
createFile新建文件ContractProvider;
deleteFile删除文件ContractProvider;
distributeContractContractProvider;
downloadContractContractProvider;
downloadContractFromOtherHostContractProvider;
generateAnnotationSampleContractProvider;
generateAppDataAnalysisContractProvider;
generateAppDataSourceContractProvider;
generateBDCoinEventProjectContractProvider;
generateBDCoinProjectContractProvider;
generateBiddingExampleContractProvider;
generateCSVProjectContractProvider;
generateContractExecutorContractProvider;
generateDAC4BDOAContractProvider;
generateDAC4BDOA_persistContractProvider;
generateDACSampleContractProvider;
generateEmptyProjectContractProvider;
generateEventPublisherContractProvider;
generateEventSubscriberContractProvider;
generateGasExampleContractProvider;
generateHelloContractProvider;
generateHttpExampleContractProvider;
generateIncentivesContractProvider;
generateJSONExampleContractProvider;
generateLedgerExampleContractProvider;
generateLedgerProjectContractProvider;
generateLicenceManagerContractProvider;
generateLoggerExampleContractProvider;
generateMySQLExampleContractProvider;
generateMySQLProjectContractProvider;
generatePostgreSQLSampleContractProvider;
generateReadmeContractProvider;
generateRenderSampleContractProvider;
generateRocksDBSampleContractProvider;
generateSM2ExampleContractProvider;
generateStaticResourceContractProvider;
generateTFLinuxContractProvider;
generategenerateTFMacContractProvider;
getProjectContractProvider;
getTemplateListContractProvider;
importContractInstanceCodeByDOIContractProvider;
listFileContractProvider;
listProjectContractProvider;
listProjectPermissionContractProvider;
listProjectsContractProvider;
renameFileContractProvider;
saveFileContractProvider;
startContractAsDebugContractProvider;
uploadFileContractProvider;
compileContractProvider;ContractInstanceManager;
evaluatesContractProvider;ContractInstanceManager;
executeContractP2PTrustfullyContractProvider;ContractInstanceManager;
getCodeByID查询代码ContractProvider;ContractInstanceManager;
getControlFlowByFileNameContractProvider;ContractInstanceManager;
getGasValueContractProvider;ContractInstanceManager;
listCompiledFilesContractProvider;ContractInstanceManager;
queryContractResourceInfoContractProvider;ContractInstanceManager;
queryFreeResourceInfoContractProvider;ContractInstanceManager;
staticVerifyContractContractProvider;ContractInstanceManager;
writeDyjsContractProvider;ContractInstanceManager;
authNodeRole授权角色NodeManager;
changeBDledger修改账本配置NodeManager;
changeIpPortNodeManager;
changeNodeCenter修改集群地址NodeManager;
changeNodeNameNodeManager;
changeIpPortNodeManager;
changeDOIPConfigNodeManager;
changeYJSPathNodeManager;
countNodeLogGroupByCategoryNodeManager;
countRoleNodeManager;
deleteRoleNodeManager;
downloadUUID废弃NodeManager;
getEncodedUUID废弃NodeManager;
getPeerIDNodeManager;
listAllAuthRoleNodeManager;
listNodeInfosNodeManager;
listUnAuthRoleNodeManager;
loadConfigNodeManager;
loadNodeConfigNodeManager;
lockEditNodeManager;
unlockEditNodeManager;
updateConfigNodeManager;
uploadLicenceNodeManager;
applyNodeRole申请角色任意角色
executeContract调用合约任意角色
getConnCount任意角色
getHashAbstractLocally任意角色
getHashLocally任意角色
getNodeRoleDeprecated查询当前角色任意角色
getSessionID任意角色
listAdapters任意角色
listTheContractProcess任意角色
login登录任意角色
longStr任意角色
ping任意角色
queryDataByHash任意角色
queryDataByHashLocally任意角色
queryHashByOffset任意角色
queryHashByRequestID任意角色
queryHashSize任意角色
queryLedgers任意角色
queryRole任意角色
queryTransactionByHash任意角色
sendTransaction任意角色
setLogStage任意角色
+
+

合约准入中心角色划分

+

共分为两类角色:CenterManager和NodeManager。其中,CenterManager拥有对集群设置的权限。 +NodeManager可以增加、删除节点等操作。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
接口说明角色
authNodeManagerCenterManager;
countActionLogByCategoryCenterManager;
countCMLogByCategoryCenterManager;
deleteCenterManager;
listAllUsersCenterManager;
listApplyListCenterManager;
listLicenceCenterManager;
queryActionLogCenterManager;
queryCMLogCenterManager;
updateLicenceCenterManager;
addNodeCenterManager;NodeManager;
changeNCFileCenterManager;NodeManager;
changeOtherNCCenterManager;NodeManager;
createTrustUnit创建可信集群CenterManager;NodeManager;
deleteTrustUnitCenterManager;NodeManager;
getNCFileCenterManager;NodeManager;
getNodeTrustUnitsCenterManager;NodeManager;
getOtherNCCenterManager;NodeManager;
listContractProcessCenterManager;NodeManager;
listMultiPointContractProcessCenterManager;NodeManager;
listNodesCenterManager;NodeManager;
listTrustUnitsCenterManager;NodeManager;
queryUserStatCenterManager;NodeManager;
stopMultiPointContractProcessCenterManager;NodeManager;
applyRoleNodeManager;
executeContract调用合约任意角色
executeContractTrustfully任意角色
getManagerPubkey任意角色
getNodeRole任意角色
getNodeSessionID任意角色
getRole任意角色
getSessionID任意角色
login登录任意角色
+
+
+
+

合约节点Http接口

+

http://xxx.xxx.xxx.xxx:1717/SCIDE/SCManager为提供Http接口服务的服务器 URL(xxx.xxx.xxx.xxx:1717为BDWare SCIDE运行的IP和端口号) , 用户可通过在URL后附加字段参数, 完成以下功能. +http://xxx.xxx.xxx.xxx:18000/SCIDE/SCManager 为提供Http接口服务的服务器

+

URL(xxx.xxx.xxx.xxx:1717 为BDWare SCIDE运行的IP和端口号),用户可通过在URL后附加字段参数,完成以下功能:

+
+

用户管理类

+
+

ping

+

ping服务器测试

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionping
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=ping
+
+
+
+
+
返回结果示例
+
{"data":"pong"}
+
+
+
+
+
+
+

合约代码管理类

+
+

下载合约项目

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiondownloadContract
projectName合约项目名
isPrivate是否在私有目录下
pubKey用户公钥
timestamp时间戳
sign签名
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=downloadContract&projectName=BDCoin&isPrivate=false&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3
+8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275
+
+
+
+
+
+

上传文件

+
+
方法
+

POST

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
path文件上传路径
fileName待上传文件名
isPrivate是否在私有目录下
order第几个数据包
count数据包总数
timestamp时间戳
sign签名
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/Upload?path=/TEST/TEST.yjs&fileName=WechatIMG15.jpeg&isPrivate=true&order=0&count=3&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05&sign=dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275
+
+
+
+
+
返回结果示例
+
{"status":"true","data":"success"}
+
+
+
+
+
+

保存合约脚本

+

向服务器发送请求, 向服务器本地保存合约脚本内容.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionwriteDyjs
target合约脚本文件名
content合约脚本内容
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=writeDyjs&target=testyjs.yjs&content=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onWriteDyjs",
+    "data": "success"
+}
+
+
+

后续用户可启动并调用该合约.

+
+
+
+
+

合约实例管理类

+
+

查询合约进程

+

向服务器发送请求, 查询服务器上已经启动的所有合约进程.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistContractProcess
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=listContractProcess
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onListContractProcess",
+    "data": "[\n  {\n    \"id\": \"-562752842\",\n    \"name\": \"shortc\",\n    \"port\": \"1626\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  }\n]"
+}
+
+
+
+
+
+

启动合约

+

向服务器发送请求, 启动某个合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionstartContract
script合约脚本内容, 需进行进行URIEncode
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContract&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D
+
+
+
+
+
返回结果示例
+
{
+    "data": "{\"status\":\"Success\",\"result\":\"\"}",
+    "action": "onStartContract",
+    "cid": "-562752842",
+    "executeTime": 1187
+}
+
+
+
+
+
+

调用合约

+

向服务器发送请求, 调用某个合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionexecuteContract
contractID合约ID
withDynamicAnalysistrue/false 是否进行动态分析
operation调用合约的方法名
arg调用合约的参数
pubkey可选,调用者公钥
signature可选,签名

其中pubkey为sm2的公钥,计算方式如下:

+
//sm2 可从sm2.js中加载获得。
+signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey);
+
+
+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=executeContract&contractID=-620602333&operation=main&arg=hhh
+
+
+
+
+
返回结果示例
+
{
+    "data": "{\"status\":\"Success\",\"result\":\"3\"}",
+    "action": "onExecuteResult",
+    "executeTime": "13"
+}
+
+
+
+
+
+

批量启动合约

+

向服务器发送请求, 启动服务器中保存有合约脚本的一系列合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionstartContractBatched
fileList合约脚本文件列表(Json数组,URLEncode)
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContractBatched&fileList=%5B%20%22EventPuber.yjs%22%2C%20%22EventSuber.yjs%22%2C%20%22LicenceManager.yjs%22%20%5D
+
+
+
+
+
返回结果示例
+
{"EventPuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","LicenceManager.yjs":"{\"status\":\"Success\",\"result\":\"\"}","EventSuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","action":"onStartContract"}
+
+
+
+
+
+

启动Zip包合约

+

向服务器发送请求, 启动服务器中包装为zip格式的合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstartContractInTempZips
owner调用者公钥
pathzip合约(路径及)文件名
signature调用者签名
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContractInTempZips&owner=0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55&path=traceTest.zip&signature=650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%2C72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2
+
+
+
+
+
返回结果示例
+
{"data":"verify failed","action":"onStartContract"}
+
+
+
+
+
+

获取合约代码

+

向服务器发送请求, 获取某个ID合约的脚本代码.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiongetCodeByID
contractID合约ID
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=getCodeByID&contractID=814046805
+
+
+
+
+
返回结果示例
+
{"status":true,"action":"onCodeResult","data":"@LogType(\"Arg\")\ncontract EventSuberAtCHQ{\n\t\n  \texport function init(arg){\n\t\tvar result \u003d YancloudUtil.subscribe(\"EventPuberAt3966\",\"abc\",handler);\n       // print(\"Handler:\"+handler);\n  \t \n  \t\treturn result;\n\t}\n  \texport function handler(e){\n        var ret \u003d \"ReceiveEvent:\";\n\t\tret+\u003d\"\\n\";\n      \tprint(ret);\n      \tret+\u003dYancloudUtil.executeContract(\"EventPuberAt3966\",\"notify\",\"success\");\n      \tprint(ret);\n        return ret;\n\t}\n}\n"}
+
+
+
+
+
+

保存合约状态

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondumpContract
contractID合约ID 或 合约Name=
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/SCManager?action=dumpContract&contractID=counter&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83
+
+
+
+
+
返回结果示例
+
{"data":"success","size":"3.76 KB","time":"0.03s"}
+
+
+
+
+
+

获取合约内存文件列表

+

向服务器发送请求, 获取某子文件夹中的所有内存文件列表.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistMemoryFiles
contractID合约Id 或 合约Name
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/SCManager?action=listMemoryFiles&contractID=-247468535&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b
+
+
+
+
+
返回结果示例
+
{"data":["2020-09-23.18:40:38","2020-09-24.16:03:41","2020-09-24.16:58:39","2020-09-24.18:25:47","2020-09-24.18:32:37","2020-09-24.20:54:41","2020-09-24.20:57:39","2020-09-24.21:31:07","2020-09-24.21:32:09","2020-09-24.21:36:11","2020-09-28.15:29:15","2020-09-28.20:28:29","2020-09-28.20:39:46","2020-09-28.21:45:31","2020-09-28.21:49:18","2020-09-28.22:27:34","2020-09-28.22:31:09","2020-09-28.22:32:49","2020-10-07.16:51:06","2020-10-07.16:51:23","2020-10-25.21:09:10","2020-12-14.19:06:53","2021-02-02.10:28:56","2021-02-02.10:31:13"],"action":"onListMemoryFiles"}
+
+
+
+
+
+

停止合约

+

向服务器发送请求, 停止某个合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionkillContractProcess
id合约ID
*requestID请求ID, String类型

*表示可选参数

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=killContractProcess&id=-1759263594
+
+
+
+
+
返回结果示例
+
{"status":false,"action":"onListContractProcess","data":"[\n  {\n    \"id\": \"-65051856\",\n    \"name\": \"EventSuber\",\n    \"port\": \"1631\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"814046805\",\n    \"name\": \"EventSuberAtCHQ\",\n    \"port\": \"1630\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"2023975189\",\n    \"name\": \"LicenceService\",\n    \"port\": \"1632\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"-620602333\",\n    \"name\": \"shortc\",\n    \"port\": \"1627\",\n    \"times\": \"0 \",\n    \"traffic\": \"0.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  }\n]"}
+
+
+
+
+
+

停止所有合约

+

向服务器发送请求, 停止服务器上启动的所有合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionkillAllContract
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=killAllContract
+
+
+
+
+
返回结果示例
+
{"status":false,"action":"onKillAllContract","data":"Kill:7357,7541,7548,7555,7584,7585,7591,7598,7609,7612,8440,8442,8444,8521,"}
+
+
+
+
+
+

静态分析合约

+

向服务器发送请求, 静态分析合约脚本.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionstaticVerifyContract
contractid合约ID
script请求ID, String类型
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=staticVerifyContract&contractid=943728900&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D&path=static.yjs
+
+
+
+
+
返回结果示例
+
{"data":"{\"status\":\"Success\",\"result\":\"{\\\"main\\\":\\\"Ret:arg \\\"}\"}","action":"onExecuteResult","cid":"943728900","executeTime":54}
+
+
+
+
+
+

获取合约静态分析流

+

向服务器发送请求, 获取某个合约的静态分析Control Flow.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiongetControlFlowByFileName
path合约ID
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=getControlFlowByFileName&path=EventSuber.yjs
+
+
+
+
+
返回结果示例
+
{"init":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","aload 4","invokedynamic dyn:getProp|getElem|getMethod:YancloudUtil (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B3","stmts":["dup","invokedynamic dyn:getMethod|getProp|getElem:subscribe (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B4","stmts":["swap","ldc XiaomiSmartHomeAtPKU","ldc onAirPurifierModeChange","aload 4","invokedynamic dyn:getProp|getElem|getMethod:handler (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B5","stmts":["invokedynamic dyn:call:\\\u003dYancloudUtil\\,subscribe (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B6","stmts":["\u003dL3\u003d","astore 5"],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B7","stmts":["\u003dL4\u003d","aload 5","areturn"],"original":"  \t\treturn result;"},{"type":"Continuous","name":"B8","stmts":["\u003dL5\u003d"],"original":"  \t\treturn result;"},{"type":"Continuous","name":"B9","stmts":["\u003dL6\u003d"],"original":"  \t\treturn result;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B9","label":{"label":"e"}}]},"handler":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","ldc ReceiveEvent:","aload 2","invokedynamic dyn:getProp|getElem|getMethod:content (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B3","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B4","stmts":["ldc  ","invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B5","stmts":["aload 2","invokedynamic dyn:getProp|getElem|getMethod:type (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B6","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B7","stmts":["\u003dL3\u003d","astore 5"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B8","stmts":["\u003dL4\u003d","aload 4","invokedynamic dyn:getMethod|getProp|getElem:print (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B9","stmts":["getstatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime UNDEFINED Lwrp/jdk/nashorn/internal/runtime/Undefined;","aload 5","invokedynamic dyn:call:print (Ljava/lang/Object;Lwrp/jdk/nashorn/internal/runtime/Undefined;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B10","stmts":["pop"],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B11","stmts":["\u003dL5\u003d","aload 5","areturn"],"original":"        return ret;"},{"type":"Continuous","name":"B12","stmts":["\u003dL6\u003d"],"original":"        return ret;"},{"type":"Continuous","name":"B13","stmts":["\u003dL7\u003d"],"original":"        return ret;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B8","label":{"label":"e"}},{"from":"B8","to":"B9","label":{"label":"e"}},{"from":"B9","to":"B10","label":{"label":"e"}},{"from":"B10","to":"B11","label":{"label":"e"}},{"from":"B11","to":"B13","label":{"label":"e"}}]}}
+
+
+
+
+
+
+

日志查看类

+
+

合约日志-查询数量

+
+
方法
+

GET

+

contractName为空或是不传入时,则为查询全部合约的条数

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogSize
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogSize&contractName=NanningDataSource
+
+
+
+
+
返回结果示例
+
{
+    "size": 12,
+    "action": "onQueryContractLogSize",
+    "status": "success"
+}
+
+
+
+
+
+

合约日志-根据日期查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogByDate
startlong,必须,起始时间
endlong,非必须,若无end,默认为当前时间
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByDate&start=1597296300272&end=1597296305747
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getMainFrame",
+            "costTime": "2493",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296300272,
+            "key": "-8590335427581967208"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "732",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296301030,
+            "key": "849660532962309239"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4580",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305745,
+            "key": "-8003529429500512736"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4551",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305746,
+            "key": "7604666709899222357"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305751,
+            "key": "-7561786202695627022"
+        }
+    ],
+    "action": "onQueryRecentContractLog"
+}
+
+
+
+
+
+

合约日志-根据偏移量查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogByOffset
countlong,必须,获取日志条数
offsetlong,非必须,若无offset,默认返回最新count条
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByOffset&count=5&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305842,
+            "key": "-2390672423847654148"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "isOwner",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305868,
+            "key": "6056586201629372511"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getApplyList",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305893,
+            "key": "3882409580676458151"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getAcceptList",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305908,
+            "key": "-3437513873417136535"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "analysisByIndustry",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02",
+            "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}",
+            "date": 1597296314654,
+            "key": "203156239086062402"
+        }
+    ],
+    "action": "onQueryRecentContractLog"
+}
+
+
+
+
+
+

合约日志-根据key查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogByKey
keylong,必须,该日志对应的key
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByKey&key=203156239086062402
+
+
+
+
+
返回结果
+
{
+    "data": {
+        "action": "executeContract",
+        "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+        "contractID": "-1382208250",
+        "contractName": "NanningDataSource",
+        "function": "analysisByIndustry",
+        "costTime": "6",
+        "totalGas": "0",
+        "executionGas": "0",
+        "extraGas": "0",
+        "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02",
+        "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}",
+        "date": 1597296314654
+    },
+    "action": "onQueryContractLogByKey"
+}
+
+
+
+
+
+

合约日志-按时间段统计调用次数

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actioncountContractLogGroupByCategory
startlong,必须,起始时间
end非必须,终止时间,默认为当前
intervallong,非必须,统计间隔
category非必须,合约名称以逗号连接,不传入时统计全部合约调用情况
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=countContractLogGroupByCategory&start=1596758400000&interval=86400000
+
+
+
+
+
返回结果
+
{
+    "start": 1596758400000,
+    "interval": 86400000,
+    "action": "onCountContractLogGroupByCategory",
+    "data": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        43,
+        14
+    ]
+}
+
+
+
+
+
+

账本日志-查询数量

+

查询通过本节点去账本上记录的日志数量

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryHashSize
contractName非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashSize&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "count": "2",
+    "action": "onQueryHashSize"
+}
+
+
+
+
+
+

账本日志-根据偏移量查询

+

查询x条通过本节点去账本上记录的日志的哈希列表

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryHashByOffset
count整数,必须,表示条数
offset整数,非必须,表示偏移量,不传入offset则默认返回最新count条
contractName字符串,非必须,表示合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashByOffset&count=1&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "hash": "3a6c60621907146b77146c1f2d48700e47520173",
+            "date": 1597296314658
+        }
+    ],
+    "action": "onQueryHash",
+    "status": "success"
+}
+
+
+
+
+
+

账本日志-根据hash查询详情

+

根据hash来查询日志内容

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryDataByHash
hash字符串,可通过queryHashByOffset
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryDataByHash&count=1&contractName=NanningDataSource&hash=3a6c60621907146b77146c1f2d48700e47520173
+
+
+
+
+
返回结果
+
{
+    "from": "0x3034643139323433323966373263656431343866",
+    "to": "0x65786563757465436f6e74726163740000000000",
+    "data": "1597296314655 --> {\"extraGas\":\"0\",\"totalGas\":\"0\",\"executionGas\":\"0\",\"signature\":\"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02\",\"costTime\":\"6\",\"arg\":\" {\\\\\\\"year\\\\\\\":2018,\\\\\\\"category\\\\\\\":\\\\\\\"工业\\\\\\\",\\\\\\\"indexType\\\\\\\":\\\\\\\"营业额\\\\\\\"}\",\"contractID\":\"-1382208250\",\"action\":\"analysisByIndustry\",\"pubKey\":\"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd\"}",
+    "requestID": "1597296314629_6067",
+    "action": "onQueryDataByHash"
+}
+
+
+
+
+
+

账本日志-根据requestID查询Hash

+

根据requestID来查询日志内容,需由开发者保证requestID的唯一性

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryHashByRequestID
requestID字符串,在发起调用时生成
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=queryHashByRequestID&requestID=0987654321ab
+
+
+
+
+
+

节点日志-查询数量

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryNodeLogSize
category非必须,不传入时查询全部情况

其中包括:ping、startContract、saveFile等。

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize&category=login
+
+
+
+
+
返回结果
+
{
+    "size": 177,
+    "action": "onQueryNodeLogSize",
+    "status": "success"
+}
+
+
+
+
+
+

节点日志-按日期查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryNodeLogByDate
startlong,必须,起始日期
endlong,非必须
category非必须,不传入时查询全部情况
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1597376006441
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1596758400000&category=login
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "listAllAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006438,
+            "key": "387355870552374748"
+        },
+        {
+            "action": "listUnAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006441,
+            "key": "4772693258708933626"
+        },
+        {
+            "action": "countRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006444,
+            "key": "-6425375229108830572"
+        },
+        {
+            "action": "loadNodeConfig",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006448,
+            "key": "-6602401010405792959"
+        },
+        {
+            "action": "getPeerID",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006449,
+            "key": "-7006776427870311552"
+        }
+    ],
+    "action": "onQueryNodeLogByDate"
+}
+
+
+
+
+
+

节点日志-按偏移量查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryNodeLogByOffset
countlong,必须,获取日志条数
offsetlong,非必须,若无offset,默认返回最新count条
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByOffset&count=5
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "listAllAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006438,
+            "key": "387355870552374748"
+        },
+        {
+            "action": "listUnAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006441,
+            "key": "4772693258708933626"
+        },
+        {
+            "action": "countRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006444,
+            "key": "-6425375229108830572"
+        },
+        {
+            "action": "loadNodeConfig",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006448,
+            "key": "-6602401010405792959"
+        },
+        {
+            "action": "getPeerID",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006449,
+            "key": "-7006776427870311552"
+        }
+    ],
+    "action": "onQueryNodeLogByOffset"
+}
+
+
+
+
+
+

节点日志-按时间段统计调用次数

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actioncountLogGroupByCategory
startlong,必须,起始时间
end非必须,终止时间,默认为当前
intervallong,非必须,统计间隔
category非必须,action以逗号连接,不传入时统计全部调用情况

其中,category中的action为NodePortal的接口的action集合。 +包括:ping、startContract、saveFile等。

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000&category=ping,startContract
+
+
+
+
+
返回结果
+
{
+    "start": 1596758400000,
+    "interval": 86400000,
+    "action": "onCountNodeLogGroupByCategory",
+    "data": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        912,
+        761
+    ]
+}
+
+
+
+
+
+

输出历史记录日志

+

向服务器发送请求, 获取节点服务器上合约的TimeTravel日志.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTimeTravelLog
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=printTimeTravelLog
+
+
+
+
+
返回结果示例
+
{"status":false,"data":"[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa_1572335939893.dyjs\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n"}
+
+
+
+
+
+

输出节点转移日志

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTransferLog
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=printTransferLog
+
+
+
+
+
返回结果示例
+
{"status":false,"data":""}
+
+
+
+
+
+
+

模板生成类

+
+
+
+
+

合约节点WebSocket接口

+
+

用户管理类

+
+

获取Session

+

登录前获取session以便进行签名。

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetSessionID
+
+
请求示例
+
var req = {};
+req.action = "getSessionID";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+	"action": "onSessionID",
+	"session": "9782323_session"
+}
+
+
+
+
+
+

用户登录

+

用户进行公私钥身份验证

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlogin
+
+
请求示例
+
var loginParam = {};
+loginParam.pubKey = global.sm2Key.publicKey;
+loginParam.signature = sm2.doSignature(global.session,
+			global.sm2Key.privateKey);
+loginParam.action = "login";
+wssocket.send(JSON.stringify(loginParam));
+
+
+
+
+
返回结果
+
{
+	"action": "onLogin",
+	"data": "NodeManager,ContractProvider"
+}
+
+
+
+
+
+

申请角色

+

在节点管理员界面申请可以申请称为合约管理员(ContractInstanceManager)、合约使用者(ContractUser)、合约提供者(ContractProvider)

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionapplyNodeRole
role申请角色名称
+
+
请求示例
+
var param = {};
+param.action = "applyNodeRole";
+param.role = "ContractUser";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onApplyRole",
+	"data": "success"
+}
+
+{
+    "action":"onApplyRole",
+    "data":"already has!"
+}
+
+
+
+
+
+

授权角色

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionauthNodeRole
isAcceptbool类型,表示否授权
pubKey授权用户公钥
+
+
请求示例
+
var param = {};
+param.action = "authNodeRole";
+param.isAccept = true;
+param.pubKey = "xxxxx";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onAuthNodeRole",
+	"data": "success"
+}
+
+
+
+
+
+

删除用户角色

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondeleteRole
role删除角色名称
+
+
请求示例
+
var deleteInfo = {};
+deleteInfo.pubKey = global.authorizedUsers.[publicKey];
+deleteInfo.action = "deleteRole";
+deleteInfo.role="ContractUser";
+wssocket.send(JSON.stringify(deleteInfo));
+
+
+
+
+
返回结果
+
{
+	"action": "onDeleteRole",
+	"data": "success"
+}
+
+
+
+
+
+

查看授权用户列表

+

查看准入管理员当前组网中已经授权的节点管理员

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistAllAuthRole
+
+
请求示例
+
var param = {};
+param.action = "listAllAuthRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onListAllAuthRole",
+    "data":
+    {
+        "kv":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab",
+              "value":"NodeManager,ContractProvider,ContractUser,ContractInstanceManager"}],
+        "time":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab",
+                "value":"1617178709933"}]
+    }
+}
+
+
+
+
+
+

查看申请用户列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistUnAuthRole
+
+
请求示例
+
var param = {};
+param.action = "listUnAuthRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onListUnAuthRole",
+	 "kv": [{
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": "ContractProvider,ContractUser"
+    }],
+    "time": [{
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": "1587398989914"
+    }]
+}
+
+
+
+
+
参数(删除)
+ + + + + + + + + + + + + +
字段
actionqueryUserStat
+
+
请求示例
+
var param = {};
+param.action = "queryUserStat";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onQueryUserStat",
+	"userListCount": 3,
+	"applyListCount":0
+}
+
+
+
+
+
+
+

合约代码管理类

+
+

获取公共合约文件列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistProjects
+
+
请求示例
+
var request = {};
+request.action = "listProjects";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\",\"BiddingExample\",\"ContractExecutor\"]",
+    "executeTime":0,
+    "isPrivate":false
+}
+
+
+
+
+
+

获取私有合约文件列表

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionlistProjects
pubKey该用户的公钥
isPrivatetrue
+
+
请求示例
+
var request = {};
+request.action = "listProjects";
+request.pubKey = "global.sm2.publicKey";
+request.isPrivate=true;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+

获取合约实例

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistContractProcess
+
+
请求示例
+
var request = {};
+request.action = "listContractProcess";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onListContractProcess",
+    "data":"[{\"id\": \"1658407837\",\"name\": \"BDCoin\",\"port\": \"1617\"}]"
+}
+
+
+
+
+
+

启动合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstartContract
ownerpubkey
requestID当前时间
script脚本内容
signature签名
+
+
请求示例
+
request.action = "startContract";
+request.owner = global.sm2Key.publicKey;
+request.requestID = new Date().getTime() + "";
+request.script = global.projectScript;
+request.signature = sm2.doSignature("Algorithm|" + request.script + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey);
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":\"\",\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}",
+    "action":"onStartContract",
+    "cid":"-506393888",
+    "executeTime":2496,
+    "responseID":"1617206735696"
+}
+
+
+
+
+
+

启动可信集群合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstartContractP2PTrustfully
ownerpubkey
isPrivate当前时间
path脚本所在路径
signature签名
peersID可信执行集群中的节点peerID组成的数组
+
+
请求示例
+
var request = {};
+request.action = "startContractP2PTrustfully";
+request.peersID = ["3r729hf2ehf982","sjdfiwoehfwoi34","wnfnwoeifnwenef"];
+var project = "JsonTest";
+request.path = "/" + project + "/mainfest.json";
+request.isPrivate = false;
+request.signature = sm2.doSignature("Trusted|" + request.path + "|"
++ global.sm2Key.publicKey, global.sm2Key.privateKey);  //合约的签名
+request.resultcheck = $("#resultcheck")[0].value;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"status\":\"Success\",\"result\":\"\"}",
+    "action":"onStartContractP2PTrustfully",
+    "cid":"-1543583350",
+    "executeTime":1544
+}
+
+
+
+
+
+

分发合约项目

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiondistributeContract
peersID集群中节点peer
projectName合约名
isPrivate是否在私有目录
sponsorPeerID发起者ID
signature签名
+
+
请求示例
+
request.action = "distributeContract";
+request.peersID = peersID;
+request.projectName = global.projects[global.lastClickedProjectId];
+request.isPrivate = $("#privateDir-tab").hasClass("active"); 
+request.sponsorPeerID = global.peerID;
+request.signature = sm2.doSignature("DistributeContract|" + request.projectName + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey);  
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+	"action":"onDistributeContract",
+	"progress":"100.00%"
+}
+
+
+
+
+
+

终止合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionkillContractProcess
id合约id
requestID请求ID
+
+
请求示例
+
request.action = "killContractProcess";
+request.id = contractid;
+request.requestID = new Date().getTime() + "";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data": "ContractHandler: exit in 3 seconds!",
+    "action": "onOutputStream"
+}
+
+
+
+
+
+

终止所有合约

+
+
参数
+ + + + + + + + + + + + + +
字段
actionkillAllContract
+
+
请求示例
+
request.action = "killAllContract";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+   	"status":false,
+   	"action":"onKillAllContract",
+   	"data":"Kill:7241,7245,"
+}
+
+
+
+
+
+

静态分析合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstaticVerifyContract
owner用户私钥
isPartial是否是部分
contractidcontractid
script脚本内容
path合约文件名
+
+
请求示例
+
request.action = "staticVerifyContract";
+request.owner = global.sm2Key.privateKey
+request.isPartial = false;
+request.contractid = contractid;
+request.script = global.projectScript;
+request.path = global.projectName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":{\"hello\":\"Ret:\"},\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}",
+    "action":"onStaticVerifyResult",
+    "cid":"verify",
+    "executeTime":83
+}
+
+
+
+
+
+

删除合约

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondeleteFile
filefileName
+
+
请求示例
+
request.action = "deleteFile";
+request.file = fileName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onDeleteFile",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

私有合约传至公共目录

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionchangePublic
pubkey用户公钥
fileNamefileName
+
+
请求示例
+
request.action = "changePublic";
+request.pubkey = pubkey;
+request.fileName = fileName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onChangePublic",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

上传合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionUploadFile
isAppendfalse
fileNamefileName
pathpath
isPrivatetrue/false
contentfileContent(base64编码)
+
+
请求示例
+
request.action = "uploadFile";
+request.isAppend = false;
+request.fileName = "test1.yjs";
+request.path = "test1";
+text="Y29udHJhY3QgdGVzdDF7CglleHBvcnQgZnVuY3Rpb24gaGVsbG8oYXJnKXsgCiAgICAgICAgcmV0dXJuICJ3b3JsZCI7ICAKICAgIH0gICAKfQ=="
+request.content = text;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onUploadFile",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

编译合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actioncompile
pathstring, 待编译的项目名称
privateTabbool, 是否为私有目录的项目
+
+
请求示例
+
var req = {"action":"compile","path":"Hello","privateTab":true}
+
+
+
+
+
返回结果
+
{"result":"Hello_2020-08-17-09:09:40.ypk","action":"onCompile"}
+
+
+
+
+
+

锁定私有目录

+

锁定某个用户的的私有目录编辑功能

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlockEdit
pubKeystring, 要被锁定的公钥
+
+
请求示例
+
var req = {};
+req.action = "lockEdit";
+req.pubKey = "xxxxxx";
+wssocket.send(JSON.stringify(req));
+
+
+
{
+    "action":"onLockEdit",
+    "status":"success",
+    "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1"
+}
+
+
+
+
+
+

解锁私有目录

+

解锁某个用户的的私有目录编辑功能

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionunLockEdit
pubKeystring, 要被锁定的公钥
+
+
请求示例
+
var req = {};
+req.action = unlockEdit;
+req.pubKey = "xxxxxx";
+wssocket.send(JSON.stringify(req));
+
+
+
{
+    "action":"onUnlockEdit",
+    "status":"success",
+    "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1"
+}
+
+
+
+
+
+
+

合约实例管理类

+
+

查询合约进程

+

向服务器发送请求, 查询服务器上已经启动的所有合约进程.

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistContractProcess
+
+
请求示例
+
var request = {};
+request.action = "listContractProcess";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+	"status": false,
+	"action": "onListContractProcess",
+	"data": "[...]"
+}
+
+
+
+
+
+

调用合约

+

向服务器发送请求, 调用某个合约.

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionexecuteContract
contractID合约ID
withDynamicAnalysistrue/false 是否进行动态分析,可选
operation调用合约的方法名
arg调用合约的参数
pubkey调用者公钥,可选
signature调用者签名 ,可选

*表示可选参数

+
//sm2 可从sm2.js中加载获得。
+signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey);
+
+
+
+
+
请求示例
+
var request = {};
+request.action = "executeContract";
+request.contractID = "2073401446";
+request.operation = "main";
+request.arg = "hhhhh";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "needSeq":false,
+    "seq":0,
+    "status":"Success",
+    "result":"world",
+    "isInsnLimit":false,
+    "totalGas":0,
+    "executionGas":0,
+    "extraGas":0,
+    "size":0,
+    "eventRelated":false,
+    "responseID":"1617211077264_223",
+    "action":"onExecuteResult",
+    "executeTime":"5"
+}
+
+
+
+
+
+

输出历史记录日志(删除)

+

向服务器发送请求, 获取节点服务器上合约的TimeTravel日志.

+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTimeTravelLog
+
+
请求示例
+
var request = {};
+request.action = "printTimeTravelLog";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+	"status": false,
+	"data": "[CMActions] dumpContract :…t/contractExamples/memoryDumps/LicenceManager\n"
+}
+
+
+
+
+
+

输出节点转移日志(删除)

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTransferLog
+
+
请求示例
+
var request = {};
+request.action = "printTransferLog";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
 {
+	"status": false,
+	"data": ""
+}
+
+
+
+
+
+

合约状态迁移

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionloadMemory
contractName合约名称
memoryFile合约文件名称
+
+
请求示例
+
var request = {};
+request.action = "loadMemory";
+request.contractName = "JsonContract";
+request.memoryFile = "2020-03-17.20/42/55";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "data":"success",
+    "size":"0.00 B",
+    "action":"onTransferTo",
+    "time":"0.01s"
+}
+
+
+
+
+
+
+

日志查看类

+
+

查看本地近n日节点日志(删除)

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistLocalNodeLog
date当前时间
+
+
请求示例
+
request.action = "listLocalNodeLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+   "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]"
+}
+
+
+
+
+
+

查看本地近n日合约日志(删除)

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistLocalContractLog
date当前时间
+
+
请求示例
+
request.action = "listLocalContractLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]"
+}
+
+
+
+
+
+
+

节点配置类

+
+

获取节点配置信息

+
+
参数
+ + + + + + + + + + + + + +
字段
actionloadNodeConfig
+
+
请求示例
+
var param = {};
+param.action = "loadNodeConfig";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onLoadNodeConfig",
+	"data": {
+		"nodeName": "04BF52213343C147E631B877BCEB17B794230EE551E85F58FA429C4BA03D690778CC384C6916C63DF36CB9E35C7E274FDB4E18491DFE3D611D347856D441CACC5AF9090B515F02AFC2DFBF56461EC83B5A4CD342466360D6CF82E6E40B637430AC4A329CCBC798DAF7D526AF9E3B3600E0BEA1BFAB8C160EF90128FAF67B19E45F37664F1E4B",
+		"licence": "04AADCC7103CD02626D228AFFBEF53F8242ECA4DDD6F179D30B622440666715CFBB6FD1D3678A2B25812DEA9917073E79A65F7ADE517F784DC76288EFCEB37ECAA1025E6903540702F729DA1C2ECCD93F4E6FAFCE40DF443E7FD74387169D0C6D927C7BB12882D0471C8D3E6F31B0316A42FC38F6DD9978D4351B23B2AD63E2244909E98F51185D32CB99B4AE4E22D3AB4C04027BB",
+		"expireTime": "Wed Aug 26 09:43:08 CST 2020",
+		"nodes": "[\"node1\",\"node2\",\"node3\"]",
+		"yjsPath": "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar",
+		"nodeCenter": "ws://127.0.0.1:1719/SCIDE/NodeCenter"
+	}
+}
+
+{ 
+    "status":true,
+    "action":"onLoadNodeConfig",
+    "data":{  
+        "nodeName":"Node_180",
+        "peerID":"",
+        "masterAddress":"39.104.201.40:21031",
+        "licence":"04AADCC7103C",
+        "doipConfig":"{\\"LHSProxyAddress\\":\\"http://39.104.201.40:21042/\\",\\"ownerHandle\\":\\"86.5000.470/dou.TEST\\",\\"certPath\\":\\"keys/dou.TEST.keystore\\",\\"certPassword\\":\\"123456\\",\\"repoID\\":\\"86.5000.470/doip.vcg9Mu1gSq_bdw\\",\\"listeners\\":\\"[{\\\\\\"url\\\\\\":\\\\\\"tcp://39.104.201.40:21032\\\\\\",\\\\\\"protocolVersion\\\\\\":\\\\\\"2.1\\\\\\",\\\\\\"messageFormat\\\\\\":\\\\\\"packet\\\\\\"}]\\",\\"serviceDescription\\":\\"test local Contract Repository\\",\\"serviceName\\":\\"ContractEngine021\\"}",
+        "clusterConnected":"false",
+        "nodePubKey":"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5",
+        "ipPort":"",
+        "bdledger":"39.108.56.240:18091,39.108.56.12:1809139.104.70.160:18091 47.98.247.70:18091 47.98.248.208:18091 39.104.77.165:18091 47.98.249.131:18091",
+        "yjsPath":"/data/bdwaas/bdcontract/yjs.jar",
+        "nodeCenter":"ws://39.104.201.21040/SCIDE/NodeCenter"
+    }
+}
+
+
+
+
+
+

修改节点配置

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionupdateConfig
key要改的配置项
val要更改的目标值

其中,key的可选项包括:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
key的示val示例说明
yjsPath/User/xxx/cp/yjs.jar合约进程启动所需的jar
dataChain192.168.1.8:18090,182.173.2.3:18091账本节点的ip与端口
nodeCenterws://127.0.0.1:18002CenterPortal所在的ip/端口
nodeNameNode_180字符串类型
masterAddress192.168.3.2:18001该NodePortal节点的ip和的TCP端口

其中NodePortal的TCP端口为Node的http/ws端口号+1。

+
+
+
+

修改节点名称

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeNodeName
data新的节点名称
+
+
请求示例
+
var param = {};
+param.action = "changeNodeName";
+param.data = "NewNodeName";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeNodeName",
+	"data": true
+}
+
+
+
+
+
+

修改节点YJS路径

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeYJSPath
data节点服务器yjs.jar路径
+
+
请求示例
+
var param = {};
+param.action = "changeYJSPath";
+param.data = "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeYJSPath",
+	"data": true
+}
+
+
+
+
+
+

修改NodeCenter

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeNodeCenter
data节点服务器要连接的NodeCenterWebSocket路径
+
+
请求示例
+
var param = {};
+param.action = "changeNodeCenter";
+param.data = "ws://127.0.0.1:1719/SCIDE/NodeCenter";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeNodeCenter",
+	"data": true
+}
+
+
+
+
+
+

修改账本节点

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeBDledger
data数链节点的IP:port,用","隔开
+
+
请求示例
+
var param = {};
+param.action = "changeBDledger";
+param.data = "39.108.56.240:18091,39.108.56.12:18091";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeBDledger",
+	"data": true
+}
+
+
+
+
+
+

上传节点Licence

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionuploadLicence
data节点服务器的Licence内容
+
+
请求示例
+
var param = {};
+param.action = "uploadLicence";
+param.data = "04AADCC7103C";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onUploadLicence",
+	"data": true
+}
+
+
+
+
+
+

获取节点ID

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetNodeID
+
+
请求示例
+
var param = {};
+param.action = "getNodeID";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onGetNodeID",
+	"data": "0431…d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d"
+}
+
+
+
+
+
+

获取节点所在的可信执行集群

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongetNodeTrustUnits
data节点ID
msgHandler收到回复的回调函数, 可使用"建立连接"的msgHandler
ws节点所属的NodeCenter的WebSocket地址
+
+
请求示例
+
centerportalws = createWssocket("ws://127.0.0.1:1718/NodeCenterWS",function() {
+var param = {};
+param.action = "getNodeTrustUnits";
+param.data = "0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d";
+centerportalws.send(JSON.stringify(param));
+}, msgHandler);
+
+
+
+
+
返回结果
+
{
+	"data": [{
+		"key": "0475c7b061...65e55_4063665700873624164",
+		"value": "[\"04541429c11b094…40009b4f06d\"]"
+	}],
+	"action": "onGetNodeTrustUnits"
+}
+
+
+
+
+
+
+

模板生成类

+
+

获取合约模板列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetTemplateList
+
+
请求示例
+
req={};
+req.action = "getTemplateList";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "formDesc": {
+                "dbPWD": {
+                    "label": "密码",
+                    "type": "input"
+                },
+                "contractName": {
+                    "label": "合约名称",
+                    "type": "input"
+                },
+                "accessPolicy": {
+                    "label": "访问控制策略",
+                    "type": "input",
+                    "option": [
+                        {
+                            "text": "无访问控制",
+                            "value": "NAC"
+                        },
+                        {
+                            "text": "直接访问控制",
+                            "value": "DAC"
+                        },
+                        {
+                            "text": "基于角色的访问控制",
+                            "value": "RBAC"
+                        }
+                    ]
+                },
+                "dbUserName": {
+                    "label": "用户名",
+                    "type": "input"
+                },
+                "fieldList": {
+                    "label": "字段名",
+                    "type": "tag"
+                },
+                "dbUrl": {
+                    "label": "数据库链接",
+                    "type": "input"
+                },
+                "tableName": {
+                    "label": "表名",
+                    "type": "input"
+                }
+            },
+            "apiName": "generateMySQLProject"
+        },
+        {
+            "formDesc": {
+                "contractName": {
+                    "label": "合约名称",
+                    "type": "input"
+                },
+                "accessPolicy": {
+                    "label": "访问控制策略",
+                    "type": "input",
+                    "option": [
+                        {
+                            "text": "无访问控制",
+                            "value": "NAC"
+                        },
+                        {
+                            "text": "直接访问控制",
+                            "value": "DAC"
+                        },
+                        {
+                            "text": "基于角色的访问控制",
+                            "value": "RBAC"
+                        }
+                    ]
+                }
+            },
+            "apiName": "generateEmptyProject"
+        }
+    ],
+    "action": "onTemplateList"
+}
+
+
+
+
+
+

空白合约模板

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongenerateEmptyProject
contractName字符串类型,合约名称
isPrivate布尔类型,是否为私有项目
accessPolicy若为"DAC",则实现直接访问控制
+
+
请求示例
+
var req = {};
+req.contractName = "Empty22";
+req.action = "generateEmptyProject";
+req.accessPolicy = "DAC";
+//wssocket为建立好的连接
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\"]",
+    "executeTime":0,
+    "isPrivate":false
+}
+
+
+
+
+
+

MySQL接入合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongenerateMySQLProject
contractName字符串类型,合约名称
isPrivate布尔类型,是否为私有项目
dbUrl字符串类型,数据库的URI
dbUserName字符串类型,数据库的用户名
dbPWD字符串类型,数据库密码
accessPolicy若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制
tableName字符串类型,数据库的表名
fieldList字符串列表,数据库的字段列表
defaultAccept布尔值,表示申请时是否默认有权
+
+
请求示例
+
var req = {};
+req.contractName = "MySQLFromTemplate";
+req.action = "generateMySQLProject";
+req.pubKey = global.sm2Key.publicKey;
+req.isPrivate = true;
+req.tableName = "data";
+req.dbUrl = "jdbc:mysql://xxx:xxx/xxx";
+req.dbUserName = "loushuai";
+req.dbPWD = "loushuai";
+req.fieldList = [{"name":"名字","code":"*"}];
+req.basicInfo={"type":"所属分类","name":"资源名称"};
+req.accessPolicy = "DAC";
+req.defaultAccept = true;
+//global.wssocket为建立好的连接
+global.wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+

CSV接入合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongenerateCSVProject
contractName字符串类型,合约名称
base64EncodedData字符串类型,通过base64编码后的CSV文件内容
isPrivate可选字段,布尔类型,是否为私有项目
accessPolicy若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制
defaultAccept可选字段,布尔值,表示申请时是否默认有权
+
+
请求示例
+
var req = {};
+req.contractName = "CSVFromTemplate";
+req.action = "generateCSVProject";
+req.pubKey = global.sm2Key.publicKey;
+req.isPrivate = true;
+req.tableName = "data";
+req.accessPolicy = "DAC";
+req.defaultAccept = true;
+req.base64EncodedData = "bmFtZSwgc2NvcmUsCmphY2ssIDkwLApsdWN5LCA5MQo=";
+//global.wssocket为建立好的连接
+global.wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+
+
+
+

路由节点WebSocket接口

+
+

用户管理类

+
+

获取Session

+

登录前获取session以便进行签名。

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetSessionID
+
+
请求示例
+
var req = {};
+req.action = "getSessionID";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+	"action": "onSessionID",
+	"session": "9782323_session"
+}
+
+
+
+
+
+

用户登录

+

用户进行公私钥身份验证,需先调用”getSessionID”获取sessionID以便于签名。

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlogin
+
+
请求示例
+
var loginParam = {};
+loginParam.pubKey = global.sm2Key.publicKey;
+loginParam.signature = sm2.doSignature(global.session,
+			global.sm2Key.privateKey);
+loginParam.action = "login";
+wssocket.send(JSON.stringify(loginParam));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onLogin",
+	"data": "CenterManager"
+}
+
+
+
+
+
+

用户获取当前角色(删除)

+

用户根据登录时的公钥获取对应的角色,如果是第一次登录则此时的公钥默认称为准入管理员

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetRole
+
+
请求示例
+
var param = {};
+param.action = "getRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onGetRole",
+	"data": "CenterManager"
+}
+
+
+
+
+
+

申请角色

+

在准入管理员界面可以申请称为组网中某个节点的节点管理员

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionapplyRole
role申请的角色名称
+
+
请求示例
+
var param = {};
+param.action = "applyRole";
+param.role="
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onApplyRole",
+	"data": "failed"
+}
+
+
+
+
+
+

添加节点

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionaddNode
nodePubKey要添加的节点公钥
+
+
+

请求示例

+
var req = {};
+//某节点的publicKey可通过连接该节点,并通过"获取节点配置信息"接口获取
+req.nodePubKey = publicKey;
+req.action = "addNode";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+

删除用户角色

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondelete
pubKey对应用户的公钥
+
+
请求示例
+
var deleteInfo = {};
+deleteInfo.pubKey = user.publicKey;
+deleteInfo.action = "delete";
+wssocket.send(JSON.stringify(deleteInfo));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onDelete",
+	"data": "success"
+}
+
+
+
+
+
+

查看授权用户列表

+

查看准入管理员当前组网中已经授权的节点管理员

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistAllUsers
+
+
请求示例
+
var param = {};
+param.action = "onListAllUsers";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onListAllUsers",
+	 "kv": {
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": " NodeManager"
+    },
+    "time": {
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": 1587398989914
+    }
+}
+
+
+
+
+
+

查看申请用户列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistApplyList
+
+
请求示例
+
var param = {};
+param.action = "onListApplyList";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onListApplyList",
+	 "kv": {
+        "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7",
+        "value": " NodeManager"
+    },
+    "time": {
+        "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7",
+        "value": 1587398989914
+    }
+}
+
+
+
+
+
+

查看用户类型分布

+
+
参数
+ + + + + + + + + + + + + +
字段
actionqueryUserStat
+
+
请求示例
+
var param = {};
+param.action = "onQueryUserStat";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onQueryUserStat",
+	"userListCount": 3,
+	"applyListCount":0
+}
+
+
+
+
+
+
+

节点管理类

+
+

查看节点列表

+

查看该用户有权限查看的节点列表(仅准入管理员及合约管理者可用)

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistNodes
+
+
请求示例
+
var param = {};
+param.action = "listNodes";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"offline": [{
+		"key": "0431e31...40009b4f06d",
+		"value": "0431e311bd708...b4f06d"
+	}],
+	"action": "onListNodes",
+	"online": [{
+		"contracts": [],
+		"pubKey": "0431e311...09b4f06d",
+		"nodeName": "NewNodeName",
+		"udpID": "528822126",
+		"cimanager": ""
+	}]
+}
+
+
+
+
+
+

查看可信执行集群列表

+

查看该用户有权限查看的节点列表(仅中心管理员及合约管理者可用)

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistTrustUnits
+
+
请求示例
+
var param = {};
+param.action = "listTrustUnits";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"data": [{
+		"key": "0470b2f27f4f6…1cb855f1ecec11",
+		"value": "[...]"
+	}],
+	"action": "onListTrustUnits"
+}
+
+
+
+
+
+

建立可信执行集群

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actioncreateTrustUnit
data节点公钥组成的Json数组
Msg集群名称
+
+
请求示例
+
var param = {};
+param.action = "createTrustUnit";
+param.data = "[\"382r0934309t...\",\"345343rr3f34...\"]";
+param.msg = "newUnit1";
+global.wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onCreateTrustUnit",
+	"status": "Success"
+}
+
+
+
+
+
+

删除可信执行集群

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondeleteTrustUnit
data可信执行集群ID
+
+
请求示例
+
var param = {};
+param.action = "deleteTrustUnit";
+param.data = "0475d34rf3434..._1583410158761";
+global.wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onDeleteTrustUnit",
+	"status": "Success"
+}
+
+
+
+
+
+
+

日志查看类

+
+

查看组网管理操作的统计

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryActionLog
date当前时间
+
+
请求示例
+
request.action = "onQueryActionLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{	"action":"onQueryActionLog",
+     "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]"
+}
+
+
+
+
+
+

查看本地近n日合约日志

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistLocalContractLog
date当前时间
+
+
请求示例
+
request.action = "listLocalContractLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7b...\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]"
+}
+
+
+
+
+
+
+
+
+

Bash接口

+

已废弃。可使用BDWareConfigTool代替。 +通过命令行发送Socket指令, 执行调用ContractController类中方法, 完成以下功能. (需要在本机的1615端口运行ContractManager实例)

+

Bash接口功能示意图

+
+

指令

+
java -jar yjs.jar function_name arguments
+
+
+

function_name为调用的方法名;

+

arguments为方法参数.

+
+
+

启动合约

+
+

参数

+

function_namestartContract;

+

arguments为启动合约需要的参数, 包括合约类型type, 合约IDid, 合约脚本script.

+
+
+

指令示例

+
java -jar yjs.jar startContract "{\"type\":\"Algorigthm\",\"id\":\"656565\",\"script\":\"contract c{function main(arg){return arg/1.0+1;}}\"}"
+
+
+
+
+
+

调用合约

+
+

参数

+

function_nameexecuteContract;

+

arguments为调用合约需要的参数, 包括调用参数arg, 合约IDcontractID.

+
+
+

指令示例

+
java -jar yjs.jar executeContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}"
+
+
+
+
+
+

停止合约

+
+

参数

+

function_namestopContract;

+

arguments为调用合约需要的参数, 即合约IDcontractID.

+
+
+

指令示例

+
java -jar yjs.jar stopContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}"
+
+
+
+
+
+

停止全部合约

+
+

参数

+

function_namestopAllContracts.

+
+
+

指令示例

+
java -jar yjs.jar stopAllContracts 
+
+
+
+
+
+

查询全部合约

+
+

参数

+

function_namelistContracts.

+
+
+

指令示例

+
java -jar yjs.jar listContracts 
+
+
+
+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown/IDEUsage.html b/doc/markdown/IDEUsage.html new file mode 100644 index 0000000..e749a17 --- /dev/null +++ b/doc/markdown/IDEUsage.html @@ -0,0 +1,614 @@ + + + + + + + + + + BDContract管理界面 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract管理界面

+
+
+

合约节点管理界面

+

该界面的使用地址为:NodePortal.html

+
+

用户管理菜单

+

用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。

+
+

概览

+

nodeUserManager +节点用户管理页面一共有四个模块:用户情况、用户活跃统计、授权用户管理、未授权用户管理。

+
+
+

用户类型分布

+

主要统计当前节点管理员所拥有的四种角色的数量:合约提供者、合约管理员、合约使用者 +userList

+
+
+

用户活跃统计

+

userActive +统计30天之内登录授权申请的次数

+
+
+

当前用户信息

+

nodeInfo

+
    +
  • 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录节点管理员界面,可以将自己的公私钥复制到这个文本框中。

  • +
  • 将自己的公私钥复制完成之后要点击导入公钥,将公钥加入到节点管理员本地

  • +
  • 然后在本地公钥中可以看见公钥的前五位,选择自己的公钥,将在我的权限中展示出当前选择的公钥的角色,如果是还没有在中心管理员认证的节点则默认为Anonymous

  • +
  • 如果不是节点管理员,想要加入某个中心管理员的网络,那么要在中心管理员所在的用户管理中用自己的公私钥导入后进行认证。

  • +
  • 如果想要行使更多关于合约的操作,则需要认证不同的角色:合约管理员、合约使用者、合约提供者,然后进行角色认证

  • +
+
+
+

授权与非授权用户列表

+

roleAuth +在节点管理员认证角色之后,节点管理员登录会在未授权角色管理表格中看见带有公钥的申请信息,如果同意,则点击授权,如果不同意点击忽略就可以。 +授权之后将在授权角色管理表格中看见授权后的节点列表。如果节点管理员想要移除某个节点的角色,则在授权角色管理列表中删除即可。

+
+
+
+

合约代码管理菜单

+

codeManageMenu

+
+

合约文件

+

codeManage1

+

在合约代码管理菜单中,用户可以看到公共合约以及个人私有合约。 +codeManage1-1

+

对于公共合约,节点管理员可以对其中文件进行删除和上传操作,可以对合约项目进行下载和删除操作。 +codeManage1-2

+

对于私有合约,合约提供者可以对其中文件进行删除和上传操作,可以对合约项目进行下载、删除和传至公共合约目录操作。

+

以下是对合约文件进行操作的示例。

+
+
+

上传文件

+

codeManage6

+
+
+

删除

+

codeManage5

+
+
+

传至公共

+

codeManage7

+
+
+

下拉框

+

codeManage2

+

四个下拉框中,可以分别对合约状态保存模式、已启动合约实例、节点所在集群以及结果校验方式进行选择。

+
+
+

按钮操作

+

codeManage3

+
+
+

启动

+

在文件列表中选择合约文件之后,在合约运行模式中选择“单节点执行”,点击启动按钮,会启动指定文件,并在结果显示框中显示返回结果。

+
+
+

启动P2P集群合约

+

在文件列表中选择合约文件之后,在合约运行模式中选择该可信合约运行的合约集群,点击启动按钮,会在该集群的所有节点上启动指定文件,并在结果显示框中显示返回结果。

+
+
+

启动全部

+

在合约运行模式中选择“单节点执行”,点击启动全部按钮,会启动合约文件列表中所有合约。

+
+
+

停止P2P集群合约

+

在已启动合约实例的下拉框中选择一个合约实例,在合约运行模式中选择该可信合约运行的合约集群,点击停止按钮,会在该集群的所有节点上终止这个合约进程。

+
+
+

停止

+

在已启动合约实例的下拉框中选择一个合约实例,点击停止按钮,会终止这个合约进程。

+
+
+

停止全部

+

点击停止全部按钮,会停止该节点上运行的所有合约实例。

+
+
+

静态分析

+

在合约文件列表中选择合约文件,并在合约实例下拉框中选择合约实例,点击静态分析按钮,会对该合约进行静态分析,并在结果显示框中显示返回结果。

+
+
+

分发合约

+

在合约文件列表中选择合约项目,并在合约运行模式中选择一个集群,点击分发合约按钮,会将该合约项目打包为ypk分发给这个集群中的所有节点。

+
+
+

返回结果

+

codeManage4

+

返回结果显示中显示一些操作的返回结果。

+
+
+

合约权限配置

+

在启动合约之后,如果当前用户的角色可以查看已经启动合约进程,那么在选定查看合约进程时将会在右下方展示当前合约的IO权限。 +permissionShow

+

如果选中的合约没有IO权限,则在当前权限的展示框中提示当前合约没有IO权限 +nullPermission

+

当前用户是合约管理员时可以对已有的合约IO权限进行修改。系统会提示修改后合约将有可能不会正常运行,如果还是确定要取消,那么点击确定 即可,反之点击关闭 +updatePermission

+

点击关闭或者打开之后,下一次查看同一个合约代码的进程将会默认显示最近一次修改之后的IO权限。 +closePermission

+
+
+
+

合约实例管理菜单

+

nodeInstancesPage

+

合约实例管理菜单显示了该节点当前的所有合约实例, 用户可查看合约实例的状态, 并对合约实例进行执行或状态迁移的操作.

+
+

合约实例列表

+

nodeInstancesList

+

该列表显示了当前节点的所有合约实例信息, 包括合约ID, 合约名称, 合约类型合约状态, 合约进程端口, 合约调用次数, 合约流量, 及合约占用内存, 集群合约的结果校验模式.

+
+
+

合约实例执行

+

chooseInstance

+

用户可在合约实例的选择下拉框中选择合约实例, 对该合约实例进行操作.

+

intanceExecute

+

选择合约实例后, 用户可在”方法”的下拉框中选择该合约的方法名, 在”参数”输入框中输入方法的参数, 点击”执行”.

+

用户还可点击”动态分析执行”进行带有动态分析结果的执行.

+

若该合约为单点合约, 则合约在单点执行; 若该合约为集群合约, 则该合约在该集群的所有节点上执行.

+
+
+

合约实例执行结果

+

executeResult

+

合约实例的执行完成后的结果显示在”执行结果”区域中, 包括该次执行的ID, 执行成功/失败, 执行时间, 及执行结果.

+

analysisExecuteResult

+

若该合约的执行方式为”动态分析执行”, 则结果框内除执行结果, 还会显示该次执行的动态分析结果.

+
+
+

合约状态迁移

+

memoryDump

+

对于支持用户手动迁移的合约实例, 用户可点击”本地状态保存”对合约实例的状态进行保存, 或从合约的TimeTravel列表中选择已保存的合约实例, 将合约状态迁移到对应时刻.

+
+
+
+

日志管理菜单

+

logMenu

+

该菜单是对该节点本地节点日志以及合约日志的统计结果展示。

+

其中,节点管理员可以查看节点日志的相关数据;合约管理者及合约使用者可以查看该节点本地合约日志的相关数据。

+
+

日志统计图

+

log1

+
+
+

各类平台操作百分比

+

该图默认显示近2日各类平台操作占比的饼图,其中平台操作分为登陆类、用户类、日志类、合约类、维护类以及其他类这六类。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比会同步更新。

+
+
+

各类合约操作百分比

+

合约操作分为启动、终止、静态分析和执行这四类,该图为近2日对各类合约操作占比的饼图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比会同步更新。

+
+
+

每日平台使用统计

+

该图为近2日平台操作次数统计的折线图。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日平台使用统计折线图会同步更新。

+
+
+

每日合约使用统计

+

该图为近2日对该节点上合约的操作次数统计的折线图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日合约使用统计折线图会同步更新。

+
+
+

日志详情

+
+
+

节点日志详情

+

log2

+

节点日志详情表是对节点日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比和每日平台使用统计会同步更新。

+
+
+

合约日志详情

+

log3

+

合约日志详情表是对合约日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比和每日合约使用统计会同步更新。

+
+
+
+

节点管理菜单

+

nodeConfig

+

节点管理菜单显示了该节点的配置信息及所属可信执行集群信息.

+
+

节点配置

+

nodeConfigChange

+

节点管理员可查看该节点的配置信息, 包括节点名称, 节点YJS路径, 节点的网络中心节点, 节点管理员还可对以上配置进行修改.

+

若节点管理员修改了节点的网络中心, 该节点后重新想改节点连接, 整个页面刷新重载.

+
+
+

节点可信执行集群列表

+

nodeUnits

+

节点管理员可查看节点所属的可信执行集群信息, 包括集群创建者, 集群ID, 集群中节点数目, 集群中节点的信息.

+
+
+
+

节点Licence配置

+

nodeLicence

+

用户可以查看该节点的Licence及过期时间, 还可申请Licence, 上传Licence, 保存节点UUID.

+
+
+
+
+

智能合约在线编辑器

+
+

用户与账号

+
+

创建账号

+
+
+

申请授权

+
+
+
+

创建项目

+
+

新建文件

+
+
+

上传文件

+
+
+
+

启动合约

+

contractMode

+

####正常模式 +点击左侧启动按钮,以正常模式启动合约。

+

####debug模式 +点击右侧debug按钮,以debug模式启动合约。目前约定debug模式合约通过executeContract调用正常模式合约时,返回正常模式合约文档中的返回结果示例。

+
+
+

调用合约

+

###生成文档 +genReadme

+

启动合约后点击”生成文档”按钮,可以通过各export函数的@Description / @Param / @Result 对合约进行调用及结果返回,从而生成合约的说明文档。

+
+
+
+
+

路由准入管理界面

+
+

权限申请与授权

+
+
+

仪表盘

+

仪表盘为提供对准入节点中用户数量,合约数量,节点数量的概览。

+
+
+

整体视图

+

dashboard +一共分为四个模块,一个模块是用户、合约、节点数量的概览,然后分别是这三个数量的详细分类的数据统计情况。

+
+
+

节点数目

+

node +当前在线和离线节点统计

+
+
+

用户类型分布

+

userAll +当前准入节点所在组网中的节点管理员、准入管理员的数量和申请中节点的数量

+
+
+

合约调用情况

+

contract +当前准入节点所在组网中所有合约中事件、多点执行、ws调用、Http调用的折线统计图。

+
+
+

用户管理

+

用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。

+
+
+

概览

+

centerManager +用户管理页面一共有四个模块。

+
+
+

用户类型分布

+

主要统计当前中心管理员所管理的网络中有多少节点管理员,多少个中心管理以及申请节点管理员的数量 +userList

+
+
+

30天内的申请情况统计

+

userApplyGraph +统计30天之内申请节点管理员的数量和授权成为节点管理员的数量

+
+
+

当前用户信息

+

authNodeManager

+
    +
  • 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录中心管理员界面,可以将自己的公私钥复制到这个文本框中。

  • +
  • 将自己的公私钥复制完成之后要点击导入公钥,将公钥加入到中心管理员本地

  • +
  • 然后在本地公钥中可以看见公钥的前五位,选择自己的公钥,将在我的权限中展示出当前选择的公钥的角色,如果是中心管理员则拥有中心管理员的一切权限。

  • +
  • 如果不是中心管理员或者节点管理员,想要加入当前中心管理员的网络,那么可以在下面的选择框中选中节点管理员,进行角色认证

  • +
+
+
+

授权与非授权用户列表

+

在中心管理员当前用户信息申请之后,中心管理员登录会在未授权用户管理表格中看见带有公钥的申请信息,如果同意,则点击授权,如果不同意点击忽略就可以,此时这个申请就无效。 +authMan +授权之后将在授权用户管理表格中看见授权后的节点列表。如果中心管理员想要移除某个节点管理员的某项角色,则在授权用户管理列表中选择相应的角色,然后点击删除即可删除选中的角色。 +authMana

+
+
+

节点管理

+

centerNodePage

+

节点管理为Manager对连接到自己的Cluster节点进行管理的页面, 仅Manager管理员及合约管理者可见. Manager管理员及合约管理者可在本页面查看节点信息, 并管理可信执行集群.

+
+
+

概览

+

centerNodePreview

+

概览中显示了该Manager节点所管理的所有节点的统计信息, 包括总节点数量, 总合约数量, 总订阅事件数量, 及可信执行集群数量, 右侧的饼图则为节点的分别处于Online/Offline的数量统计.

+
+
+

节点列表

+

centerNodeList

+

节点列表显示了用户有权限查看的节点信息(Manager管理员可查看全部节点, 合约管理者可查看自己负责管理的Online节点). 包括节点的名称, 状态, 合约数目, 订阅事件数目, 用于节点间P2P通信的PeerID, 用于节点间UDP通信的UDPID, 及节点公钥.

+
+
+

可信执行集群列表

+

centerNodeUnits

+

可信执行集群列表显示了用户有权限查看的可信执行集群信息(Manager管理员可查看全部集群, 合约管理者可查看自己创建的集群). 包括集群的创建者, 集群ID, 集群中节点数目, 以及集群中节点的信息.

+

用户可点击列表表项的”删除”按钮, 将该集群删除.

+
+
+

创建可信执行集群

+

centerNodeUnitCreate

+

用户可以通过多选节点, 创建新的可信执行集群. 用户可以选择的节点为自己有权限查看的节点, 即Manager管理员从全部节点中选择, 合约管理者可从自己负责管理的Online节点中选择). 选择后点击提交, 即可看到创建成功的提示信息, 该集群将随即显示在可信执行集群列表中. 集群名称由创建者选取, 不能含有双引号, 该名称为合约管理者选择集群时的可见标识.

+
+
+

日志管理

+

日志管理主要展示准入节点的各项日志信息,一共分为六个模块。

+
+
+

概览

+

log

+
+
+

管理操作分类统计(2日)

+

operator +两日内所有管理类操作的统计饼图,管理类操作主要分为登录类、日志类、维护类、用户类。

+
+
+

管理操作每日统计(2日)

+

everyLog +两日内管理类所有的操作每日操作统计

+
+
+

合约操作分类统计(2日)

+

contractLog +两日内合约操作分类统计饼图,合约操作主要分为连接类和状态更新类。

+
+
+

合约操作每日统计(2日)

+

contracteveryLog +两日内合约操作数量折线统计图。

+
+
+

管理操作日志列表

+

opList +管理操作日志的详细信息列表。包括日志时间,管理操作名称,操作对应的节点公钥。默认展示范围是两天,可以自定义获取日志的天数。

+
+
+

合约操作日志列表

+

contractList +合约操作日志详细信息列表。包括日志产生时间,合约操作名称,合约操作节点公钥。默认展示范围是两天,可以自定义获取日志的天数。

+
+
+

设置

+

设置页面是节点证书的状态展示以及配置节点证书

+
+
+

概览

+

set

+
+
+

证书状态

+

licence +证书状态主要包括许可到期时间和许可节点数量。

+
+
+

配置证书

+

plicence +配置证书模块可以下载节点ID文件或者输入证书信息进行提交。

+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown/InstallTips.html b/doc/markdown/InstallTips.html new file mode 100644 index 0000000..3882b81 --- /dev/null +++ b/doc/markdown/InstallTips.html @@ -0,0 +1,367 @@ + + + + + + + + + + BDContract安装说明 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract安装说明

+
+
+

依赖环境的安装

+

1.安装Java1.8环境。

+

例如,在Ubuntu下使用apt-get进行安装:

+
apt-get install openjdk-8-jre
+
+
+

在Centos环境下,使用yum进行安装:

+
yum install java-1.8.0-openjdk
+
+
+

如果是离线环境,可先下载openjdk的安装包后进行离线安装。

+

Ubuntu下

+
dpkg -i jdk-8uxxxxx.deb
+
+
+

在Centos环境下,使用yum进行离线安装:

+
yum localinstall jdk-8u271-linux-xxx.rpm
+
+
+

2.安装wget与unzip。 +例如,在Ubuntu下使用apt-get进行安装:

+
apt-get install unzip
+apt-get install wget
+
+
+
+
+
+

网络拓扑说明

+

部署数瑞智能合约引擎最小仅需一个节点,此时可用作调试、测试,不能通过多节点模式来实现可信的计算。 +单节点部署时,可通过配置账本实现”防抵赖”的计算,但不能实现”难篡改”的计算。

+

多节点部署时可参考下图,包含三种逻辑节点,同一虚拟机可安装一至三种节点。

+

1)账本节点。即数瑞图式账本。

+

2)合约节点。运行代码逻辑,并通过内存缓存实现高响应的模块。与其他合约节点组成可信计算网络。

+

3)路由节点。各个合约节点的路由信息。一般单个路由节点可支持最高1000合约节点。可视情况部署多个路由节点,并在路由节点之间配置实现更大规模的节点组网。

+

一般地,同一虚拟机下,会部署合约节点与账本节点

+

deploytopology

+
+
+
+

智能合约节点安装

+

打开安装包下载链接 +其中,下载bdserver-lite.zipbdserver.zip,其中,bdserver.zip包含更多示例和文档。 +下载之后解压并启动。

+
unzip -d ./bdserver bdserver-lite.zip
+cd bdserver
+chmod +x *.sh
+sh cmstart.sh
+
+
+
+
+
+

路由准入节点安装

+

打开安装包下载链接 +其中,下载bdserver-cluster.zip。 +下载之后解压并启动。

+
unzip -d ./bdcluster bdserver-cluster.zip
+cd bdcluster
+chmod +x *.sh
+sh ncstart.sh
+
+
+
+
+
+

文件说明

+
+

智能合约节点

+

bdserver目录

+

该目录下的文件说明:

+

1.cmstart.sh 该脚本用于启动合约引擎。合约引擎默认监听8080端口,可通过修改cmstart.sh来修改合约引擎的监听端口。

+

2.BDWareProjectDir 该目录存放了本节点的所有合约项目。

+

3.WebContent 该目录存放了本节点的前端代码。

+

4.cp, 该目录存放了yjs.jar,为启动合约实例所需的jar。

+

5.bdserver.jar 对外提供http/websocket的服务器逻辑。

+

6.updateContract.sh 用于升级的脚本。

+
+
+

路由准入节点

+

安装脚本会自动下载安装并解压为bdcluster目录。 +该目录下的文件说明:

+

1.ncstart.sh 该脚本用于启动节点准入中心。默认监听1718端口。可通过修改ncstart.sh来修改监听的端口。

+

2.WebContent 该目录存放了准入中心的前端代码。

+

3.bdcluster.jar 准入中心的后端。

+
+
+
+
+

升级流程

+
+

合约节点

+

在命令行中输入:

+
sh updateContract.sh
+
+
+

亦可通过public.internetapi.cn,下载最新文件,单独升级yjs.zip/bdserver-jar.zip/AgentWebContent来升级。

+
+
+

路由准入节点

+
sh updateCluster.sh
+
+
+

亦可通过public.internetapi.cn,下载最新文件,单独升级bdserver-cluster.zip/ClusterWebContent.zip来升级。

+
+
+
+
+

使用说明

+
+

通过参考界面使用

+

当保留了WebContent目录的情况下,可使用浏览器进行配置。 +更多请使用见左侧文档BDContract参考界面使用说明

+
+

BDWare OnlineIDE

+

打开BDWare OnlineIDE

+
+
+

BDWare NodePortal

+

打开BDWare NodePortal

+

如需组网,使用跨节点功能,则需安装路由准入中心。并按以下步骤进行配置。涉及两组公私钥。 +第一组公私钥为合约节点的、有NodeManager权限的公私钥。 +第二组公私钥为路由准入节点的、有CenterManager权限的公私钥。

+

1.打开NodePortal.html,复制该节点的NodeManager公私钥。

+

2.打开CenterPortal.html,点击右上角,将上述的NodeManager公私钥导入;并选择”NodeManager”进行身份认证。

+

3.在CenterPortal.html中切换CenterManager的公私钥,点左侧的”用户管理”,通过NodeManager的认证请求。

+

4.使用NodeManager权限的公私钥打开NodePortal.html,点击:“节点管理”菜单,并配置加入网络。 +其中,加入网络的格式为:ws://centerportal的ip:端口+1。 +配置示例

+
+
+
+

通过SDK使用

+
+

基础知识

+

Websocket

+

Sm2加密的使用

+
+
+

SDK下载

+
    +
  1. Java版本的客户端下载:BDWareJavaClient。具体使用说明请下载后解压,查看README.md,并参考ContractAPI

  2. +
+

2.Javascript版本的客户端下载:BDWareWebClient。具体使用说明请下载后解压,查看README.md,并参考ContractAPI

+

3.配置工具BDWareConfigTool。具体说明请下载后解压,使用以下命令查看帮助:

+
java -jar java-client.jar -h
+
+
+
+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown/Introduction.html b/doc/markdown/Introduction.html new file mode 100644 index 0000000..fb4b101 --- /dev/null +++ b/doc/markdown/Introduction.html @@ -0,0 +1,544 @@ + + + + + + + + + + BDContract介绍 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDContract介绍

+
+
+

什么是BDContract?

+

北大数瑞是面向大数据场景的数据资源、IoT资源、云资源的管理、调度平台。BDContract是一个可信计算框架,计算逻辑以智能合约的方式表达。通过”随机“和”冗余计算“的方式实现智能合约的可信执行。BDContract在保证智能合约的可用性、可靠性的同时,着重提升执行效率和安全性。

+
+
+
+

特点

+
    +
  1. 支持多种执行模式,权衡可用性、可靠性、正确性和效率。

  2. +
  3. 接入各种数据源。

  4. +
  5. 支持合约的细粒度监测。

  6. +
  7. 支持合约的状态。

  8. +
  9. 访问控制。

  10. +
  11. 支撑跨语言调用。

  12. +
+
+
+
+

更新日志

+
    +
  • v1.4.3 2021年6月9日

    +
      +
    • 修复SSL Renegotiate Bug

    • +
    • 实现内存不足时自动Hangup-Resume

    • +
    • 实现contract meta的硬盘持久化

    • +
    +
  • +
  • v1.4.1 2021年5月26日

    +
      +
    • 实现了事件机制中的事件语义,支持“至少一次”、“至多一次”和“只有一次”

    • +
    • 优化了合约模板

    • +
    • 增加模板配置文件

    • +
    • 优化了MockTemplate注解

    • +
    +
  • +
  • v1.4.0 2021年5月9日

    +
      +
    • 优化了ACTemplate

    • +
    • 完善了DoRepo的配置联动

    • +
    +
  • +
  • v1.3.9 2021年4月22日

    +
      +
    • 修复了doipConfig在updateConfig中不支持的bug

    • +
    • test-tool支持了sudo

    • +
    • 优化了contract-template中的ACTemplate模板

    • +
    +
  • +
  • v1.3.6 2021年4月21日

    +
      +
    • 修复了docker中无法获取cpuid的问题

    • +
    +
  • +
  • v1.3.6 2021年4月16日

    +
      +
    • 修复了部分bug

    • +
    • 修复了GRPCPool线程数量不足导致排队的bug

    • +
    • 修复了requestID分配在压力测试下可能重复的bug

    • +
    +
  • +
  • v1.3.5 2021年3月31日

    +
      +
    • 修复了部分bug

    • +
    • http的合约调用部分增加了简单拥塞控制策略

    • +
    • 稳定性提升

    • +
    +
  • +
  • v1.3.0 2021年2月1日

    +
      +
    • 优化心跳机制

    • +
    • 修复部分Bug

    • +
    • 更新SM2/SM3库

    • +
    • 更新前端签名计算方式

    • +
    +
  • +
  • v1.2.0 2020年12月11日

    +
      +
    • 优化了多节点执行模式

    • +
    • 优化了合约master路由的逻辑

    • +
    • 修复了部分bug

    • +
    • 修复文件系统相关的漏洞

    • +
    +
  • +
  • v1.1.0 2020年9月

    +
      +
    • 支持https,并更新了该部分文档

    • +
    +
  • +
  • v1.0.9 2020年8月27日

    +
      +
    • 完善IO相关工具类的文档

    • +
    • 优化合约模板:DAC持久化

    • +
    +
  • +
  • v1.0.7 2020年8月13日

    +
      +
    • 优化合约日志、账本接口

    • +
    • 优化相关接口的文档

    • +
    • 提供合约模板的websocket接口

    • +
    • 自动编译bug修复

    • +
    +
  • +
  • v1.0.5 2020年7月25日

    +
      +
    • 弱化NC的中心化作用,集群点对点连接。

    • +
    • 优化bdwareclient

    • +
    • TODO MemoryDurable

    • +
    +
  • +
  • v1.0.2 2020年7月22日

    +
      +
    • 修复CentOS7下Too Many Opened Files的Bug

    • +
    • 修复权限Bug

    • +
    • 增加权限说明

    • +
    • 修复MySQLUtil的bug

    • +
    • 升级BDLedger版本

    • +
    +
  • +
  • v1.0.1 2020年7月5日

    +
      +
    • 更新了NodePortal/CenterPortal的UI。

    • +
    • 修改了编译流程,在NodePortal中可查看编译结果,在OnlineIDE中可手动/启动时编译

    • +
    • 修改了合约分发逻辑,以编译后ypk作为分发的文件

    • +
    • 支持public目录下的ypk在多节点模式下执行时,合约故障自动恢复

    • +
    +
  • +
  • v0.99 2020年6月22日

    +
      +
    • 自定义合约方法的计费

    • +
    • 新增了GasExample、Incentives示例

    • +
    • 在客户端实现了”校验多点结果”,并优化了结果返回的方式

    • +
    • 修复断线重连后无权限提示

    • +
    +
  • +
  • v0.97 2020年5月25日

    +
      +
    • cpu等资源的计量:gas机制

    • +
    • onlineIDE.html 支持上传多个文件

    • +
    • udp方式组网进行多点执行[无定序消息]

    • +
    • bdwareclient.html,修复只包含计算逻辑的调用示例生成前缀错误

    • +
    +
  • +
  • v0.95 2020年5月19日

    +
      +
    • 修复了onlineIDE.html在的pathname有前缀时不能正确跳转bdwareclient的bug。

    • +
    • 修复了bdwareclient的pathname有前缀时自动提取url的bug。

    • +
    • 启用了合约的权限

    • +
    • 增加了NodePortal.html/OnlineIDE.html和bdwareclient.html中无权限时的提醒

    • +
    +
  • +
  • v0.90 2020年5月9日

    +
      +
    • 更改了yjs.jar/bdserver.jar的打包方式

    • +
    • 更新了install.sh/update.sh

    • +
    • onlineIDE的修改后提醒

    • +
    • onlineIDE标签页自适应宽度

    • +
    • 文件接口隔离

    • +
    +
  • +
  • v0.8 2020年4月26日

    +
      +
    • 完善文档界面和优化SDK提供方式

    • +
    • 数瑞Web客户端,客户端中所有的数据处理和如何对处理后的数据进行渲染均来自合约调用,实现可信Web应用。

    • +
    +
  • +
  • v0.78 2020年4月13日

    +
      +
    • 合约调用DAC示例

    • +
    • 支持动态修改IO权限

    • +
    • 支持合约状态自定义备份(定时)策略

    • +
    • 修复部分页面bug

    • +
    • 日志展示优化

    • +
    • 优化账本日志展示

    • +
    • 启用部分权限访问控制

    • +
    +
  • +
  • v0.7 2020年3月25日

    +
      +
    • 支持多种角色的访问控制

    • +
    • 更新了UI

    • +
    +
  • +
  • v0.6 2020年2月14日

    +
      +
    • 优化了合约进程间的通讯

    • +
    • 尝试接入P2P网络

    • +
    +
  • +
  • v0.5 2019年12月10日

    +
      +
    • 完善了3种智能合约状态记录-回放策略

    • +
    • 支持了最简单的多点执行算法(不同步)

    • +
    +
  • +
  • v0.45 2019年9月2日

    +
      +
    • 初步实现PBFT算法

    • +
    +
  • +
  • v0.4 2019年5月10日

    +
      +
    • 支持memory dump

    • +
    +
  • +
  • v0.35 2019年4月26日

    +
      +
    • 实现合约的静态分析框架

    • +
    • 支持事件的发布-订阅

    • +
    +
  • +
  • v0.3 2019年1月8日

    +
      +
    • 支持账本数据的接入

    • +
    • 合约状态上链

    • +
    +
  • +
  • v0.2 2018年10月9日

    +
      +
    • 支持Python包的自动生成

    • +
    • 支持合约打包为ypk

    • +
    • 支持文件、数据库等数据的接入

    • +
    +
  • +
  • v0.1 2018年8月6日

    +
      +
    • 定义了智能合约的语法

    • +
    • 基于nashorn引擎,实现了智能合约的执行

    • +
    +
  • +
+
+
+
+

使用开源项目说明

+

BDWareContract项目站在了许多巨人的肩膀上,感谢这些开源项目。

+

本项目的智能合约后端使用了以下开源库。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称Licence类型说明
Project NashornGPLv2使用了该项目的编译器,可以将js函数编译为java字节码
ASM OW2BSD with attribution基于asm的TreeAPI与VisitorAPI实现合约的静态分析框架
NettyApache License 2.0使用netty作为Http/Websocket的服务端
gRPCApache License 2.0使用gRPC与BDWareLedger通讯
RocksDBGPLv2后台数据库
ANTLRBSD对合约脚本的词法分析与语法分析
SM2Java国密SM2 Java语言实现

本项目的智能合约前端使用了以下开源库。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称Licence类型说明
BootstrapMIT前端的排版、样式
jQueryMIT用于操作DOM的javascript库
jQueryUIMIT前端UI构件库
DataTablesMIT表格样式
CodeMirrorMIT代码编辑框样式
eChartsApacheV2统计图表
sm-cryptoMIT国密SM2 javascript语言实现

本项目的文档使用Sphinx生成,感谢readthedocs提供文档样式。

+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown/YJSAPI.html b/doc/markdown/YJSAPI.html new file mode 100644 index 0000000..9243249 --- /dev/null +++ b/doc/markdown/YJSAPI.html @@ -0,0 +1,1931 @@ + + + + + + + + + + YJS SDK — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

YJS SDK

+
+

YJS Build-in API

+
+

内置对象 Global

+
+
+

内置对象 requester

+

该内置对象在export function里面会有值,仅当合约调用签名验证通过。

+
+
+

执行合约 executeContract

+

参数:

+
action:executeContract; 
+contractID:合约的id或名称均可;
+operation:调用合约的方法名;
+arg: 参数;格式为JSON字符串,有action与arg两个字段。
+
+
+

可选参数:

+
requestID:字符串类型,自行生成,用于查询hash
+
+
+

使用示例:

+
 function testExecutorContract(arg){
+    var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg));
+    if (ret.status == "Success"){
+      return JSON.parse(ret.result);
+    }else return null;
+  }
+
+
+
+
+

订阅事件主题 subscribe

+

参数

+
contractID:字符串类型 合约id或名称均可。
+event:字符串类型
+handler:方法名,该方法必须接受Event(内含字段topic和content)类型的唯一变量为参数;可以不是export方法
+
+
+

使用示例:

+
export function init(arg) {
+    YancloudUtil.subscribe("topic", handler);
+    print("Handler: " + handler);
+}
+
+function handler(e) {
+    print("topic: " + e.topic);
+    print("content: " + e.content);
+}
+
+
+
+
+

发布事件 pubEvent

+

参数

+
topic:字符串类型,发布的事件主题
+content:字符串类型,发布的事件内容
+
+
+

使用示例:

+
export function pub1(arg) {
+    YancloudUtil.pubEvent("topic", arg);
+    return "done";
+}
+
+
+

也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件

+
event topic;
+export function pub2(arg) {
+    topic(arg);
+    return "done";
+}
+
+
+

该写法与上面的pub1等价。

+
+
+

发布带语义事件 pubEventConstraint

+

参数

+
topic:字符串类型,发布的事件主题
+content:字符串类型,发布的事件内容
+semantics:枚举类型,作为字符串输入,事件语义
+
+
+

事件语义参数

+
    +
  • AT_LEAST_ONCE:至少一次,默认语义

  • +
  • AT_MOST_ONCE:至多一次

  • +
  • ONLY_ONCE:只有一次

  • +
+

使用示例:

+
export function pub1(arg) {
+    YancloudUtil.pubEventConstraint("topic", arg, "AT_MOST_ONCE");
+    return "done";
+}
+
+
+

也可以在合约开头声明事件,则事件名即为事件主题,此时可直接使用事件作为方法名按声明的语义发布事件

+
event AT_MOST_ONCE topic;
+export function pub2(arg) {
+    topic(arg);
+    return "done";
+}
+
+
+

该写法与上面的pub1等价。

+

事先声明的事件无论是否声明语义,都可以用后缀s作为方法名的方式调用,发布任意语义的事件:

+
event topic;
+export function pub3(arg) {
+    topics(arg, "AT_MOST_ONCE");
+    return "done";
+}
+
+
+

该写法与上面的pub1, pub2等价。

+

不带事件语义声明事件时,语义默认为至少一次(AT_LEAST_ONCE)。

+
+
+

访问资源文件

+

通过Global.Resources去加载ypk内部的资源文件。

+
+

loadAsInputStream

+

参数:

+
path:字符串类型 需要加载文件的地址
+
+
+

使用示例:

+
var file = Global.Resources.loadAsInputStream("/deleteit.txt");
+
+
+
+
+

loadAsScanner

+

参数:

+
path:字符串类型 需要加载文件的地址
+
+
+

使用示例:

+
var scanner = Global.Resources.loadAsScanner("/local.txt");
+
+
+
+
+
+
+

YJS Build-in Annotation

+
+

@Access

+

设置合约的调用是否需要签名,这里分为两种,需签名和无签名。 +其中,”verified”表示需要签名。其他则表示无需签名。

+
@Access("verified")
+export function easy(arg){
+    return "true";
+}
+
+
+
+
+

@LogType

+

LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。

+

其中,Arg表示日志中记录合约执行的参数;Result表示记录合约执行的返回结果;Branch表示记录合约执行分支。

+

例如 ,通过如下LogType注解来声明函数

+
@LogType("Arg","Result","Branch")
+export function easy(arg){
+    Global.a = "a";
+    Global.b = "b";
+    if(arg > 0)
+        return Global.a;
+    else
+        return Global.b;
+}
+
+
+
+
+

@LogLocation

+

该注解可以修饰contractfunction。 +设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地,如果没有指定为“dataware”则仅存储在本地。 +例如,通过如下LogLocation设置存储位置。

+

在BaaS平台中,可以指定账本名称,BaaS平台默认账本为default,使用 +@LogLocation("bdledger:default")。如想保存到自定义的账本,比如,”abc”账本,就使用 +@LogLocation("bdledger:abc")

+
@LogLocation("dataware")
+export function easy(arg){
+    Global.a = "a";
+}
+
+
+
+
+

@Permission

+

该注解只能修饰contract +设置合约中调用的工具类的权限,包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类,需要在注解中添加对应的授权字段,默认只有YJS自带的YancloudUtil;如果没有添加则会抛出”未授权工具类”的异常。 +这6种工具类的详细说明在本小节后续中有说明。

+
@Permission("Http","File")
+contract HttpPermission {
+    export function main(args){
+        var http=HttpUtil.httpGet(args);
+        var dir="adf/adfas/";
+        var file=FileUtil.getDir(dir);
+        return YancloudUtil.currentTimeMillis();
+    }
+}
+
+
+
+
+

@Description

+

该注解可以修饰contractfunction。 +传入合约及函数的简介,可用于生成说明文档中关于exported函数的介绍。

+
@Description("返回数据条目,无需参数")
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+

@Param

+

该注解可以修饰function。 +提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。

+
@Param({"offset":0,"count":100})
+export function get(args){
+    var offset = args.offset;
+    var count = args.count;
+    ...
+}
+
+
+
+
+

@MockTemplate

+

该注解可以修饰function。 +提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时,返回按照此格式生成的模拟数据。

+

####支持的字段类型

+
@integer 整数
+@string  字符串
+@boolean 布尔值
+@date @time @datatime 
+@word 单词  @cword 中文单词
+@first @last 英文姓,名
+@cfirst @clast @cname 中文姓,名,全名
+@url @domin @ip @email 
+@region @province @city @county 地区,省,市,县
+……
+详细格式可以参考http://mockjs.com/examples.html
+
+
+

####注意:模板的格式为{‘result’:模板}

+
//返回一个对象包含如下字段
+@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
+//返回
+{"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"}"
+
+//返回元素个数为1-5个之间的一个数组,数组的每个元素都是上述格式的一个对象
+{'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]}
+//返回
+[
+  {"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"},
+  {"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"},
+  {"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"}
+]
+
+
+
@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+

@Result

+

该注解可以修饰function。 +提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。

+
@Result(666)
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+
+

IO工具类

+
+

概览

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IO工具类名称说明
FileUtil文件操作相关的类
LedgerUtil账本操作相关的类
HttpUtilHttp接口相关的类
DOIPUtilDoIP相关的类
MySQLUtil连接mysql数据库
MongoDBUtilMongoDB连接相关的类
RocksDBUtilRocksDB(基于本地文件的k-v数据库)
BDWareTimeSeriesDBUtil基于本地文件的时间序列数据库
+
+

FileUtil

+

可以使用@Permission(“File”)来引入FileUtil对象。

+
@Permission("File")
+contract FileSample {
+...
+}
+
+
+

该对象支持以下方法:

+
+

copyTo

+

可以复制文件和目录。第一个参数是source,第二个参数是destination。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1src类型为String
2dest类型为String
+
+
使用示例
+
var ret = FileUtil.copyTo("./source.txt","./dest.txt");
+
+
+
+
+
+

getContent

+

获取文件的文本内容,当文件不存在时,返回undefined

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1path类型为String
+
+
使用示例
+
var ret = FileUtil.getContent("./source.txt");
+
+
+
+
+
+

getDir

+

获取文件所在的文件夹名,输入参数为字符串。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1path类型为String
+
+
使用示例
+
var ret = FileUtil.getDir("./parent/src.txt");
+// ret 为 "./parent/";
+
+
+
+
+
+

getFileName

+

获取文件名。输入参数为字符串。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1path类型为String
+
+
使用示例
+
var ret = FileUtil.getFileName("./parent/src.txt");
+// ret 为 "src.txt"
+
+
+
+
+
+

openFileAsPrinter

+

以PrintStream的形式打开文件。 +返回结果是java.io.PrintStream类型。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1path文件名,类型为String
2isAppend类型为boolean,表示是否往文件末尾添加
+
+
使用示例
+
var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true);
+ret.println("hello");
+ret.close();
+
+
+
+
+
+
+

LedgerUtil

+

可以使用@Permission(“Ledger”)来引入LedgerUtil对象。

+
@Permission("Ledger")
+contract LedgerExample{
+...
+}
+
+
+
+

getClient

+

获取一个连接客户端,一个参数,为对象类型。 +返回结果为LedgerClient类型,用于后续的查询账本等操作。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1address包含ip和端口两个字段
+
+
使用示例
+
var address = {};
+address.ip = "127.0.0.1";
+address.port = 18091;
+var ledgerClient = LedgerUtil.getClient(address);
+
+
+
+
+
+

queryByHash

+

根据Hash查询Transaction。 +返回结果为对象,包含from、to、type和data四个字段,均为String类型。 +其中data为按utf-8编码解析字节数组,如果存证时用的不是utf8编码,可能返回乱码。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1client通过getClient方法获得的对象
2info对象类型,有两个字段ledger和hash,均为字符串类型
+
+
使用示例
+
// ... ledgerClient = LedgerUtil.getClient(...);
+var info = {};
+info.ledger = "bdcontract";
+info.hash = "4d3b75750835092a50085127702669615b602e53";
+var ret = LedgerUtil.queryByHash(ledgerClient,info);
+print(ret.from);
+print(ret.to);
+print(ret.type);
+print(ret.data);
+
+
+
+
+
+

sendTransaction

+

存证数据。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1client通过getClient方法获得的对象
2info对象类型,有from\to\data三个字段,均为String类型
+
+
使用示例
+
// ... ledgerClient = LedgerUtil.getClient(...);
+var info = {};
+info.ledger = "bdcontract";
+info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155";
+info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155";
+info.data = "hello world";
+var ret = LedgerUtil.sendTransaction(ledgerClient,info);
+//ret为存证的哈希值
+print(ret);
+
+
+
+
+
+
+

HttpUtil

+

可以使用@Permission(“Http”)来引入HttpUtil对象。

+
@Permission("Http")
+contract HttpExample{
+...
+}
+
+
+
+

createAPIGate

+

配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1ip字符串类型,ip,端口默认为6161
+
+
使用示例
+
var ret = HttpUtil.createAPIGate("192.168.4.4");
+ret.get("com.tencent.mm","sendMsg","msg");
+print(ret);
+
+
+
+
+
+

createAPIGate

+

配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1ip字符串类型,ip
2port字符串类型,端口
+
+
使用示例
+
var ret = HttpUtil.createAPIGate("192.168.4.4", "6161");
+ret.get("com.tencent.mm","sendMsg","msg");
+print(ret);
+
+
+
+
+
+

get

+

发起Http的get请求。 +返回结果为对象类型,包含response和responseCode两个字段。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1url字符串,表示url类型
+
+
使用示例
+
var ret = HttpUtil.get("https://www.baidu.com");
+print(ret.responseCode);
+print(ret.response);
+
+
+
+
+
+

post

+

发起Http的post请求。 +返回结果为对象类型,包含response和responseCode两个字段。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1args对象类型,有url,headers和data三个字段。其中,args.headers为对象类型。
+
+
使用示例
+
var req = {};
+req.url = "https://www.baidu.com";
+req.data = "hello";
+req.header = {};
+req.header.Accept = "application/json";
+req.header["Content-Type"] = "application/json";
+var ret = HttpUtil.post(req);
+print(ret.resposeCode);
+print(ret.response);
+
+
+
+
+
+
+

DOIPUtil

+

可以使用@Permission(“DOIP”)来引入DOIPUtil对象。

+
@Permission("DOIP")
+contract DOIPExample{
+  ...
+}
+
+
+
+

call

+

调用一个DO

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型, 目标DO标识
2arg1字符串类型, 输入参数字符串
+
+
使用示例
+
var ret = DOIPUtil.call("86.5000.470/do.hello","inputString");
+
+
+
+
+
+

create

+

向一个Repository创建一个字符串类型DO

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型, 目标Repo标识
2arg1对象类型,包括doID,doBody字段
+
+
使用示例
+
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
+var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject);
+
+
+
+
+
+

delete

+

从一个Repository中删除DO

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
2arg1字符串类型 目标Repo标识
+
+
使用示例
+
var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo");
+
+
+
+
+
+

hello

+

获取目标Repository的DOIP服务信息

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标Repo标识
+
+
使用示例
+
var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo");
+
+
+
+
+
+

listOperation

+

获取目标DO支持的DOIP操作

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
+
+
使用示例
+
var ret = DOIPUtil.listOperation("86.5000.470/do.hello");
+
+
+
+
+
+

register

+

向LHS注册一个DO,返回分配的标识

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 DO所在Repo标识
2arg1字符串类型 DO格式描述字符串
+
+
使用示例
+
var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String");
+
+
+
+
+
+

reregister

+

修改LHS中DO的注册信息

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
2arg1字符串类型 DO所在Repo标识
3arg2字符串类型 DO格式描述字符串
+
+
使用示例
+
var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String");
+
+
+
+
+
+

retrieve

+

获取一个DO

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
+
+
使用示例
+
var ret = DOIPUtil.retrieve("86.5000.470/do.hello");
+
+
+
+
+
+
+

test

+

测试DOIPUtils是否可用

+
+

参数

+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 任意字符串
+
+

使用示例

+
var ret = DOIPUtil.test("hello");
+
+
+
+
+

update

+

更新目标DO

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0JS对象,包括doID,doBody字段
+
+
使用示例
+
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
+var ret = DOIPUtil.update(digitalObject);
+
+
+
+
+
+
+

SQLUtil

+

可以使用@Permission(“SQL”)来引入SQLUtil对象。 +可支持MySQL/PostgreSQL/Oracle/GuassDB200等SQL数据库。 +需要将对应的jdbc的jar上传到项目中。 +例如,要使用mysql,可上传mysql-connector-java-8.0.24.jar

+
@Permission("SQL")
+oracle MySQLExample{
+...
+}
+
+
+
+

initDriver

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1driverClass字符串类型
+
+
使用示例
+
    //使用mysql
+    SQLUtil.initDriver("com.mysql.cj.jdbc.Driver");
+    //使用postgresql
+    SQLUtil.initDriver("org.postgresql.Driver");
+    //使用oracle
+    SQLUtil.initDriver("oracle.jdbc.OracleDriver");
+
+
+
+
+
+

getConnection

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1URL字符串类型,jdbc连接
2usrName字符串类型,用户名
3pwd字符串类型,密码
+
+
使用示例
+
var url = "jdbc:mysql://xx.xx.xx:port/tableName";
+var usrName = "xxx";
+var pwd = "xxx";
+//配置好用户名和密码,url格式为ip或域名+端口,中间以”:”隔开。
+var conn = SQLUtil.getConnection(url,usrName,pwd);
+//获取数据库连接
+var sql = "select * from newele.data";
+//创建查询语句
+var statement = conn.createStatement();
+var resultSet = statement.executeQuery(sql);
+var waimailist  = [];
+//解析查询结果
+var meta = resultSet.getMetaData();
+for (;resultSet.next();){
+  var line = {};
+  for (var j=1;j<=meta.getColumnCount();j++){
+    line[meta.getColumnName(j)] = resultSet.getString(j);
+  }
+	waimailist.push(line);
+}
+
+
+

其中,getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此,可以查看: +https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html +以了解如何进行Mysql数据库操作。

+
+
+
+
+

MongoDBUtil

+

可以使用@Permission(“MongoDB”)来引入MongoDBUtil对象。

+
@Permission("MongoDB")
+contract MongoDBExample{
+...
+}
+
+
+
+

getConnection

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1URL字符串类型 数据库的URL
2port整数类型 端口号
3dbName字符串类型 数据库的名称
4usrName字符串类型 数据库的用户名
5pwd字符串类型 数据库的密码
+
+
使用示例
+

注意:port为整型,其他参数为String类型

+
var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd);
+//获取数据库对象
+var db = client.getDatabase("yancloud");
+var collection = db.getCollection("containers");
+var iter = collection.find().iterator();
+var ret ="";
+for (;iter.hasNext();){
+	ret+=iter.next().toJson();
+	ret+="\n";
+}
+
+
+

其中,getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此,可以查看: +https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClient.html

+

以了解该对象的更多方法和使用方式。

+
+
+
+
+

RocksDBUtil

+

使用@Permission(“RocksDB”)来引入RocksDBUtil对象。

+
@Permission("RocksDB")
+contract RocksDBSample {
+...
+}
+
+
+
+

loadDB

+

通过loadDB来加载一个RocksDB数据库。 +加载后,可进行get/delete/put等操作。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1path字符串类型 数据库部署的路径
2readOnly布尔类型 数据库只读
+
+
使用示例
+
@Permission("RocksDB")
+@Description("这是个使用RocksDB的参考代码")
+contract RocksDBSample{
+  function onCreate(){
+    Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false");
+  }
+  @Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}")
+  export function put(arg){
+    arg = JSON.parse(arg);
+    Global.rocksdb.put(arg.key,arg.value);
+    return "success";
+  }
+  @Description("示例参数: \"abc\"}")
+  export function get(arg){
+    return Global.rocksdb.get(arg);
+    return "failed";
+  }
+  @Description("示例参数: \"abc\"")
+  export function deleteKey(arg){
+    return Global.rocksdb.delete(arg);
+  }
+  @Description("遍历KV库,无需参数")
+  export function iter(arg){
+    var iter = Global.rocksdb.newIterator();
+    var obj = undefined;
+    var ret = {
+    };
+    for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){
+      ret[obj.key]=obj.value;
+    }
+    return JSON.stringify(ret)
+  }
+}
+
+
+
+
+
+
+

BDWareTimeSeriesDBUtil

+

使用示例

+
@Permission("BDWareTimeSeriesDB")
+contract BDWareTimeDBExample{
+  function onCreate(arg){
+    Global.dbutil = BDWareTimeSeriesDBUtil.getConnection();
+  }
+
+  export function put(arg){
+    //第一个参数为表名,第二个参数为要放的value,时间戳自动打。
+    Global.dbutil.put("defaultTable",arg);
+    return "success";
+  }
+  @Param
+  export function getCount(arg){
+    return Global.dbutil.getCount("defaultTable");
+  }
+  @Param(1617254937373)
+  export function queryByStartTime(arg){
+    var startDate = java.lang.Long.valueOf(arg);
+    //查询从开始时刻startDate到最新的数据
+    var list = Global.dbutil.query("defaultTable",startDate);
+    var ret=[];
+    print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
+    var i=0;
+    for (i=0;i<list.size();i++){
+      print(i+"-->"+list.get(i));
+      ret.push(list.get(i));
+    }
+    return ret;
+  }
+  
+  @Description("示例参数: {\"offset\":1,\"len\":1}")
+  @Param({"offset":1,"len":1})
+  export function queryByOffset(arg){
+    var offsetLen = JSON.parse(arg);
+    //可配合getCount使用,查询第offset至offset+len条数据
+    var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len);
+    var ret=[];
+    print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
+    var i=0;
+    for (i=0;i<list.size();i++){
+      print(i+"-->"+list.get(i));
+      ret.push(list.get(i));
+    }
+    return ret;
+  }
+}
+
+
+
+
+
+

加解密工具类

+
+

SM2

+

可以使用@Permission(“SM2”)来引入SM2Util对象。

+
@Permission("SM2")
+contract SM2Sample {
+...
+}
+
+
+
+

generateKeyPair

+

生成公私钥。

+
+
参数
+

无参数。

+
+
+
使用示例
+
var ret = SM2Util.generateKeyPair();
+print(ret.publicKey);
+print(ret.privateKey);
+return JSON.stringify(ret);
+
+
+
+
+
+

sign

+

签名。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1content字符串类型 要进行签名的内容
2keyPairsm2
+
+
使用示例
+
var keypair = SM2Util.generateKeyPair();
+var ret = SM2Util.sign("Hello",keypair);
+print(ret.status);
+//如果status是success
+print(ret.signature);
+//如果status是failed
+print(ret.message);
+
+
+
+
+
+

verify

+

验签。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1content字符串类型 待验签的内容
2signature字符串类型 签名
3publicKey字符串类型 公钥
+
+
使用示例
+
var ret = SM2Util.verify("Hello","....签名","...公钥");
+// 验证通过时,result为true,status为success
+// 失败时,result为failed,status为failed
+print(ret.status);
+print(ret.result);
+
+
+
+
+
+
+
+

多线程工具类

+
+

AsyncUtil

+

可以使用@Permission(“Async”)来引入AsyncUtil对象。

+
@Permission("Async")
+contract AsyncExample{
+  export function longTimeTask(arg){
+    var a = {
+    };
+    a.count = 100;
+    AsyncUtil.postFunction(taskFun,a);
+  }
+  function taskFun(arg){
+    Global.progress = 0;
+    for (var i=0;i<arg.count;i++){
+      AsyncUtil.sleep(100);
+      Global.progress++;
+    }
+  }
+  export function getProgress(arg){
+    return Global.progress;
+  }
+}
+
+
+
+

postFunction

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0ScriptFunction
2arg1对象
+
+
使用示例
+
var ret = AsyncUtil.postFunction(a,{"a":"b"});
+
+
+
+
+
+

setInterval

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0ScriptFunction
2arg1long
3arg2long
4arg3对象
+
+
使用示例
+
var ret = AsyncUtil.setInterval(a,100,1000,"abc");
+
+
+
+
+
+

setTimeOut

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0ScriptFunction
2arg1long
3arg2Object
+
+
使用示例
+
var ret = AsyncUtil.setTimeOut(a,100,"abc");
+
+
+
+
+
+

sleep

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0long
+
+
使用示例
+
var ret = AsyncUtil.sleep();
+
+
+
+
+
+
+ +
+

YJS应用框架

+
+

加载流程

+

函数约定(getMainFrame)

+
+
+

前端函数说明

+

executeCurrentContract/….. +如何loadScript/loadCss..

+
+
+

后端函数约定

+

getMainFrame

+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown/YJSInDepth.html b/doc/markdown/YJSInDepth.html new file mode 100644 index 0000000..303af71 --- /dev/null +++ b/doc/markdown/YJSInDepth.html @@ -0,0 +1,457 @@ + + + + + + + + + + YJS语法 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

YJS语法

+
+
+

概述

+

YJS源文件包括任意数量的import声明和一个contract定义

+
+
+
+

import声明

+

与JavaScript(ES6)类似,YJS也支持import声明语句,在全局层面,开发者可以使用如下import声明来导入其他文件。

+
import "filename";
+
+
+
+

内容

+

import声明语句将包含在“filename”文件中的所有全局符号(单元)导入到当前文件,且全局范围内有效。

+
+
+

路径

+

filename通常用**/做目录分隔符来表示文件的路径,例如,从同一目录下导入x.yjs文件到当前文件,可以使用import “x.yjs”语句;从其他目录下导入x.yjs使用import “lib/x.yjs”**语句。

+
+
+
+
+

Contract定义

+
+

示例

+

以下是一个合约示例,用于JSON处理,此YJS源文件以合约名称命名。

+
contract ScoreAdder{
+	//arg =  {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"}
+	export function main(arg){
+		//JSON is a build-in object.
+		var point = JSON.parse(arg);
+		var s = 0;
+		print(point[0].score);
+		print(point.length);
+		for (var i=0;i<point.length;i++){
+			s+=point[i].score/1.0;
+		}
+		print("total score= "+s);
+		return s;
+	}
+}
+
+
+
+
+

注释

+

YJS源文件支持以(//)表示的单行注释和以(/*…*/)表示的多行注释,如下所示:

+
// 这是一个单行注释
+/*
+ * 这是一个
+ * 多行注释
+ */
+
+
+
+
+

注解

+

与Java类似,YJS也支持注解声明合约和函数。

+

在YJS中,有几种内建注解:LogType、LogLocation、Access、Permission。 +当然,可以自定义注解。 +内建注解的详细使用方式可以通过YJS内置API文档查看。 +开发者可以使用如下注解来声明合约和函数。

+
@LogType("Arg","Result","Branch")
+@SelfDefinedAnntation("dad",1)
+@Access
+function xxx(){}
+
+
+
+
+

结构

+

YJS中的合约类似于Java中的类。每个合约都定义了一定数量的变量函数事件

+
+

变量

+

YJS中的变量类似于JavaScript(ES6)中的变量,分为全局变量局部变量

+

全局变量:

+
judge =  true;
+
+
+

局部变量:

+
var vs = "This is a string";
+
+
+

所有的变量都是动态类型,因为变量的具体类型是根据变量值来决定的。如上示例中,全局变量judge是bool类型,局部变量vs是字符串类型。

+
+
+

函数

+

函数是合约中的可执行单元。YJS中有两种类型的函数:普通函数和用export关键字修饰的exported函数。

+

以下是exported函数和普通函数的区别:

+
    +
  1. 只有exported函数能被其他合约调用。

  2. +
  3. exported函数只能有一个参数且参数类型必须为String。

  4. +
  5. exported函数的返回类型必须是String。

  6. +
  7. 内置对象requester(请求者的公钥)只能存在于exported函数或onCreate函数,因为onCreate()虽然没被export关键字修饰,但它自带requester对象且该函数可以自动执行。

  8. +
+
+
+

事件

+

YJS中的事件类似于Solidity中的事件。

+

发布者定义一个包含事件发布函数的事件,然后通过调用事件发布函数发布事件。

+

订阅者订阅并处理事件。

+

事件示例如下:

+

EventPuber.yjs

+
contract EventPuber{
+	event abcEvent;
+  	export function pub(arg){
+		abcEvent(arg);
+  		return "done!";
+	}
+}
+
+
+

EventSuber.yjs

+
contract EventSuber{
+  	export function init(arg){
+		YancloudUtil.subscribe("EventPuber","abcEvent",handler);
+        print("Handler:"+handler);
+	}
+  	function handler(e){
+        var ret = "ReceiveEvent:"+(e.type)+" "+(e.content);
+		print(ret);
+	}
+}
+
+
+
+
+
+
+
+

YJS项目

+

除了只包含一个contract定义的YJS源文件,YJS引擎还支持YJS项目

+

每个YJS project包含了合约执行过程中需用到的各种文件,包括yjs源文件**”.yjs”和其他资源文件,如”mainfest.json”, “.js”, “.txt”,”.jar”**, …

+
+

Manifest.json

+

每个YJS项目在项目的根目录下必须有一个mainfest.json文件,此文件描述了合约对于YJS的编译工具(YJS引擎)所需的必要信息。

+
+

Manifest结构

+

manifest文件需包含以下信息:

+
    +
  1. main: 项目中将要被执行的合约文件。

  2. +
  3. type: 合约的类型,如数据合约/算法合约…

  4. +
  5. builder: 构建YJS项目的开发者姓名。

  6. +
  7. insnLimit: 运行合约需要消耗的值。

  8. +
  9. pyDependences: 项目所需的Python依赖。

  10. +
+
+
+

Manifest示例

+
{
+	"main": "contract.js",
+	"type": "Data",
+	"builder": "caihq",
+	"permissions": 0L,
+	"pyDependences": [
+        {
+            "name": "yjsexample",
+            "modules": [
+                {
+                    "name": "sample"
+                }
+            ]
+        }
+    ]
+}
+
+
+
+
+
+

YJS-Java

+

Jar文件实现了YJS与其他编程语言间的跨语言调用,如YJS-Java, YJS-Python, … 通过将Java文件包成jar包的方式,使得合约可直接调用Java中的方法。

+

Java class:

+
package your.own.pkg;
+public class HelloWorld {
+ public static int fun(String arg){
+  return arg.length;
+ }
+ public int fun2(String arg){
+  return arg.length;
+ }
+}
+
+
+

InvokeJava.yjs

+
contract InvokeJava{
+ export function main(arg){
+  var Hello = Java.type("your.own.package.HelloWorld");
+  var hello = new Hello();
+  return Hello.fun(arg)+hello.fun2(arg);
+ }
+}
+
+
+
+
+

YJS-前端

+

使用数瑞客户端来访问智能合约支持从智能合约中获取html/js/css等资源文件, +并在BDWareWebClient中渲染。 +首先在合约中import以下模块。

+
module Viewable{
+  export function loadResource(arg){
+    return Global.Resources.loadAsString(arg);
+  }
+  export function needRender(arg){
+    return true;
+  }
+}
+
+
+

同时,import以后,定义一个getMainFrame方法,以便数瑞客户端识别主页:

+
export function getMainFrame(arg){
+  return "/html/main.html";
+}
+
+
+

该方法的返回结果为一个资源文件的路径。 +示例的资源文件”/html/main.html”如下:

+
<div>
+<button onclick="queryDataFromContract()">Hello,</button> Data from contract:
+<span id="resultText"></span>
+<script fromContract="/html/hello.js"></script>
+<link fromContract="/html/hello.css"/>
+</div>
+
+
+

示例的资源文件”/html/hello.js”如下:

+
var queryDataFromContract = function(){
+    //第一个参数为函数名,第二个为参数,第三个参数为回调。
+	var data = executeCurrentContract("query","abc",function(argg){
+    	$("#resultText")[0].innerHTML = argg.result;
+    });
+}
+
+
+

参考示例:

+
+
+

YJS-Python

+

TODO

+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/ContractAPI.html b/doc/markdown_BDWare/ContractAPI.html new file mode 100644 index 0000000..4507d1c --- /dev/null +++ b/doc/markdown_BDWare/ContractAPI.html @@ -0,0 +1,6371 @@ + + + + + + + + + + BDware SDK — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

BDware SDK

+

除使用可视化的智能合约在线IDE外,用户还可使用WebSocket接口、Http接口、Bash接口来启动和运行合约.

+
+
+

WebSocketSDK下载与安装

+

合约SDK提供javascript版本与java版本的客户端。

+

java客户端的下载链接为:java sourcejar +可参考java_source下的README.md及测试用例。

+

javascript的下载链接为:js SDK +内置的SM2加密库链接:sm2 SDK

+
+

建立连接

+

建立与节点服务器之间的WebSocket连接.

+
+

参数

+ + + + + + + + + + + + + + + + + +
字段
url建立WebSocket的服务器URL. 使用http协议时, 前缀为ws://, 如"ws://localhost:1717/SCIDE/SCExecutor"; 使用https协议时, 前缀为wss://
msgHandler收到服务器WebSocket回复后的回调函数, 用户可自行编写, 也可参考下面提供的示例
+
+

请求示例

+
var url = "ws://127.0.0.1:1717/SCIDE/SCExecutor";//与Slave节点建立连接
+//var url = "ws://127.0.0.1:1718/NodeCenterWS";//与Manager节点建立连接
+var msgHandler = function(m){
+  console.log("recmsg:");
+  console.log(m);
+};
+var onOpenHandler=undefined;
+wssocket = createWssocket(url,onOpenHandler,msgHandler);
+
+
+
+
+

返回结果示例

+
{
+  receiveSeg: [Function (anonymous)],
+  isSending: false,
+  sendList: [],
+  monitor: [Function (anonymous)],
+  send: [Function (anonymous)],
+  sendNextSegment: [Function (anonymous)],
+  isOpen: [Function (anonymous)]
+}
+
+
+
+
+
+

ping

+

ping服务器测试

+
+

参数

+ + + + + + + + + + + + + +
字段
actionping
+
+

请求示例

+
var request = {};
+request.action = "ping";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+

返回结果示例

+
{
+    "action":"pong"
+}
+
+
+
+
+
+

登录

+

使用Websocket接口调用需要权限的接口时,不论是连接CenterPortal还是NodePortal必须先登录。 +登录的流程有3步:

+
    +
  • 客户端向服务端建立连接,连接建立完成后发送{“action”:”getSessionID”}(可在onOpenHandler中实现)

  • +
  • 服务端收到请求后,会向客户端返回类似{“action”:”onGetSessionID”,”session”:”-4959947809200104526_session”}的结果

  • +
  • 客户端收到onGetSessionID后,会使用本地的公私钥对sessionID进行签名,并调用login接口

  • +
  • 服务端会返回onLogin的结果,data字段返回的是该公钥对应的角色。

  • +
+
+
+
+
+

用户角色划分

+
+

合约节点的角色划分

+

在合约节点(NodePortal.html)中分为NodeManager/ContractProvider/ContractInstanceManager/ContractUser四类角色。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
角色说明
NodeManager该节点的管理者,拥有用户管理、节点配置等权限
ContractProvider拥有编辑合约、开发合约代码、运行调试等权限
ContractInstanceManager拥有启、停合约实例、配置合约实例IO等权限
ContractUser拥有查看合约实例列表、调用合约等权限
Anonymous匿名用户,可以调用合约,可以申请成为ContractProvider/InstanceManager等角色
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
接口说明角色
changeDumpPeriod设置备份周期ContractInstanceManager;
createLedger创建账本ContractInstanceManager;
dumpContract手动备份ContractInstanceManager;
deleteMemoryFile删除镜像ContractInstanceManager;
forkContract迁移合约ContractInstanceManager;
getDumpPeriod获取备份周期ContractInstanceManager;
killAllContract停止全部实例ContractInstanceManager;
killContractProcess停止某一实例ContractInstanceManager;
listMemoryFiles列取某一实例的镜像ContractInstanceManager;
loadMemory加载镜像ContractInstanceManager;
queryContractInstanceDOI查询合约实例信息ContractInstanceManager;
rebuildHashIndexContractInstanceManager;
setPermissionContractProvider;ContractInstanceManager;
startContract启动合约ContractInstanceManager;
startContractBatched废弃ContractInstanceManager;
startContractByYPK启动合约ContractInstanceManager;
startContractInTempZips废弃ContractInstanceManager;
startContractP2PTrustfully启动合约(集群模式)ContractInstanceManager;
updateContractContractInstanceManager;
connectTo连接合约实例输出流ContractInstanceManager;ContractUser;
countContractLogGroupByActionContractInstanceManager;ContractUser;
countContractLogGroupByCategoryContractInstanceManager;ContractUser;
getLastLog查询日志ContractInstanceManager;ContractUser;
getLog查询日志ContractInstanceManager;ContractUser;
getLogSize查询日志ContractInstanceManager;ContractUser;
listAllContractProcessContractInstanceManager;ContractUser;
listContractProcess查询合约实例列表ContractInstanceManager;ContractUser;
listLeakContractProcessContractInstanceManager;ContractUser;
queryContractLogByDateContractInstanceManager;ContractUser;
queryContractLogByKeyContractInstanceManager;ContractUser;
queryContractLogByOffsetContractInstanceManager;ContractUser;
queryContractLogDetailContractInstanceManager;ContractUser;
queryContractLogSizeContractInstanceManager;ContractUser;
queryNodeLogByDateContractInstanceManager;ContractUser;
queryNodeLogByOffsetContractInstanceManager;ContractUser;
queryNodeLogSizeContractInstanceManager;ContractUser;
rebuildContractLogIndexContractInstanceManager;ContractUser;
rebuildNodeLogIndexContractInstanceManager;ContractUser;
changePublicContractProvider;
createFile新建文件ContractProvider;
deleteFile删除文件ContractProvider;
distributeContractContractProvider;
downloadContractContractProvider;
downloadContractFromOtherHostContractProvider;
generateAnnotationSampleContractProvider;
generateAppDataAnalysisContractProvider;
generateAppDataSourceContractProvider;
generateBDCoinEventProjectContractProvider;
generateBDCoinProjectContractProvider;
generateBiddingExampleContractProvider;
generateCSVProjectContractProvider;
generateContractExecutorContractProvider;
generateDAC4BDOAContractProvider;
generateDAC4BDOA_persistContractProvider;
generateDACSampleContractProvider;
generateEmptyProjectContractProvider;
generateEventPublisherContractProvider;
generateEventSubscriberContractProvider;
generateGasExampleContractProvider;
generateHelloContractProvider;
generateHttpExampleContractProvider;
generateIncentivesContractProvider;
generateJSONExampleContractProvider;
generateLedgerExampleContractProvider;
generateLedgerProjectContractProvider;
generateLicenceManagerContractProvider;
generateLoggerExampleContractProvider;
generateMySQLExampleContractProvider;
generateMySQLProjectContractProvider;
generatePostgreSQLSampleContractProvider;
generateReadmeContractProvider;
generateRenderSampleContractProvider;
generateRocksDBSampleContractProvider;
generateSM2ExampleContractProvider;
generateStaticResourceContractProvider;
generateTFLinuxContractProvider;
generategenerateTFMacContractProvider;
getProjectContractProvider;
getTemplateListContractProvider;
importContractInstanceCodeByDOIContractProvider;
listFileContractProvider;
listProjectContractProvider;
listProjectPermissionContractProvider;
listProjectsContractProvider;
renameFileContractProvider;
saveFileContractProvider;
startContractAsDebugContractProvider;
uploadFileContractProvider;
compileContractProvider;ContractInstanceManager;
evaluatesContractProvider;ContractInstanceManager;
executeContractP2PTrustfullyContractProvider;ContractInstanceManager;
getCodeByID查询代码ContractProvider;ContractInstanceManager;
getControlFlowByFileNameContractProvider;ContractInstanceManager;
getGasValueContractProvider;ContractInstanceManager;
listCompiledFilesContractProvider;ContractInstanceManager;
queryContractResourceInfoContractProvider;ContractInstanceManager;
queryFreeResourceInfoContractProvider;ContractInstanceManager;
staticVerifyContractContractProvider;ContractInstanceManager;
writeDyjsContractProvider;ContractInstanceManager;
authNodeRole授权角色NodeManager;
changeBDledger修改账本配置NodeManager;
changeIpPortNodeManager;
changeNodeCenter修改集群地址NodeManager;
changeNodeNameNodeManager;
changeIpPortNodeManager;
changeDOIPConfigNodeManager;
changeYJSPathNodeManager;
countNodeLogGroupByCategoryNodeManager;
countRoleNodeManager;
deleteRoleNodeManager;
downloadUUID废弃NodeManager;
getEncodedUUID废弃NodeManager;
getPeerIDNodeManager;
listAllAuthRoleNodeManager;
listNodeInfosNodeManager;
listUnAuthRoleNodeManager;
loadConfigNodeManager;
loadNodeConfigNodeManager;
lockEditNodeManager;
unlockEditNodeManager;
updateConfigNodeManager;
uploadLicenceNodeManager;
applyNodeRole申请角色任意角色
executeContract调用合约任意角色
getConnCount任意角色
getHashAbstractLocally任意角色
getHashLocally任意角色
getNodeRoleDeprecated查询当前角色任意角色
getSessionID任意角色
listAdapters任意角色
listTheContractProcess任意角色
login登录任意角色
longStr任意角色
ping任意角色
queryDataByHash任意角色
queryDataByHashLocally任意角色
queryHashByOffset任意角色
queryHashByRequestID任意角色
queryHashSize任意角色
queryLedgers任意角色
queryRole任意角色
queryTransactionByHash任意角色
sendTransaction任意角色
setLogStage任意角色
+
+

合约准入中心角色划分

+

共分为两类角色:CenterManager和NodeManager。其中,CenterManager拥有对集群设置的权限。 +NodeManager可以增加、删除节点等操作。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
接口说明角色
authNodeManagerCenterManager;
countActionLogByCategoryCenterManager;
countCMLogByCategoryCenterManager;
deleteCenterManager;
listAllUsersCenterManager;
listApplyListCenterManager;
listLicenceCenterManager;
queryActionLogCenterManager;
queryCMLogCenterManager;
updateLicenceCenterManager;
addNodeCenterManager;NodeManager;
changeNCFileCenterManager;NodeManager;
changeOtherNCCenterManager;NodeManager;
createTrustUnit创建可信集群CenterManager;NodeManager;
deleteTrustUnitCenterManager;NodeManager;
getNCFileCenterManager;NodeManager;
getNodeTrustUnitsCenterManager;NodeManager;
getOtherNCCenterManager;NodeManager;
listContractProcessCenterManager;NodeManager;
listMultiPointContractProcessCenterManager;NodeManager;
listNodesCenterManager;NodeManager;
listTrustUnitsCenterManager;NodeManager;
queryUserStatCenterManager;NodeManager;
stopMultiPointContractProcessCenterManager;NodeManager;
applyRoleNodeManager;
executeContract调用合约任意角色
executeContractTrustfully任意角色
getManagerPubkey任意角色
getNodeRole任意角色
getNodeSessionID任意角色
getRole任意角色
getSessionID任意角色
login登录任意角色
+
+
+
+

合约节点Http接口

+

http://xxx.xxx.xxx.xxx:1717/SCIDE/SCManager为提供Http接口服务的服务器 URL(xxx.xxx.xxx.xxx:1717为BDWare SCIDE运行的IP和端口号) , 用户可通过在URL后附加字段参数, 完成以下功能. +http://xxx.xxx.xxx.xxx:18000/SCIDE/SCManager 为提供Http接口服务的服务器

+

URL(xxx.xxx.xxx.xxx:1717 为BDWare SCIDE运行的IP和端口号),用户可通过在URL后附加字段参数,完成以下功能:

+
+

用户管理类

+
+

ping

+

ping服务器测试

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionping
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=ping
+
+
+
+
+
返回结果示例
+
{"data":"pong"}
+
+
+
+
+
+
+

合约代码管理类

+
+

下载合约项目

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiondownloadContract
projectName合约项目名
isPrivate是否在私有目录下
pubKey用户公钥
timestamp时间戳
sign签名
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=downloadContract&projectName=BDCoin&isPrivate=false&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3
+8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275
+
+
+
+
+
+

上传文件

+
+
方法
+

POST

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
path文件上传路径
fileName待上传文件名
isPrivate是否在私有目录下
order第几个数据包
count数据包总数
timestamp时间戳
sign签名
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/Upload?path=/TEST/TEST.yjs&fileName=WechatIMG15.jpeg&isPrivate=true&order=0&count=3&pubKey=0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05&sign=dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275
+
+
+
+
+
返回结果示例
+
{"status":"true","data":"success"}
+
+
+
+
+
+

保存合约脚本

+

向服务器发送请求, 向服务器本地保存合约脚本内容.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionwriteDyjs
target合约脚本文件名
content合约脚本内容
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=writeDyjs&target=testyjs.yjs&content=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onWriteDyjs",
+    "data": "success"
+}
+
+
+

后续用户可启动并调用该合约.

+
+
+
+
+

合约实例管理类

+
+

查询合约进程

+

向服务器发送请求, 查询服务器上已经启动的所有合约进程.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistContractProcess
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=listContractProcess
+
+
+
+
+
返回结果示例
+
{
+    "status": false,
+    "action": "onListContractProcess",
+    "data": "[\n  {\n    \"id\": \"-562752842\",\n    \"name\": \"shortc\",\n    \"port\": \"1626\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  }\n]"
+}
+
+
+
+
+
+

启动合约

+

向服务器发送请求, 启动某个合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionstartContract
script合约脚本内容, 需进行进行URIEncode
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContract&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D
+
+
+
+
+
返回结果示例
+
{
+    "data": "{\"status\":\"Success\",\"result\":\"\"}",
+    "action": "onStartContract",
+    "cid": "-562752842",
+    "executeTime": 1187
+}
+
+
+
+
+
+

调用合约

+

向服务器发送请求, 调用某个合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionexecuteContract
contractID合约ID
withDynamicAnalysistrue/false 是否进行动态分析
operation调用合约的方法名
arg调用合约的参数
pubkey可选,调用者公钥
signature可选,签名

其中pubkey为sm2的公钥,计算方式如下:

+
//sm2 可从sm2.js中加载获得。
+signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey);
+
+
+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=executeContract&contractID=-620602333&operation=main&arg=hhh
+
+
+
+
+
返回结果示例
+
{
+    "data": "{\"status\":\"Success\",\"result\":\"3\"}",
+    "action": "onExecuteResult",
+    "executeTime": "13"
+}
+
+
+
+
+
+

批量启动合约

+

向服务器发送请求, 启动服务器中保存有合约脚本的一系列合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionstartContractBatched
fileList合约脚本文件列表(Json数组,URLEncode)
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContractBatched&fileList=%5B%20%22EventPuber.yjs%22%2C%20%22EventSuber.yjs%22%2C%20%22LicenceManager.yjs%22%20%5D
+
+
+
+
+
返回结果示例
+
{"EventPuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","LicenceManager.yjs":"{\"status\":\"Success\",\"result\":\"\"}","EventSuber.yjs":"{\"status\":\"Success\",\"result\":\"\"}","action":"onStartContract"}
+
+
+
+
+
+

启动Zip包合约

+

向服务器发送请求, 启动服务器中包装为zip格式的合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstartContractInTempZips
owner调用者公钥
pathzip合约(路径及)文件名
signature调用者签名
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=startContractInTempZips&owner=0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55&path=traceTest.zip&signature=650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%2C72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2
+
+
+
+
+
返回结果示例
+
{"data":"verify failed","action":"onStartContract"}
+
+
+
+
+
+

获取合约代码

+

向服务器发送请求, 获取某个ID合约的脚本代码.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiongetCodeByID
contractID合约ID
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=getCodeByID&contractID=814046805
+
+
+
+
+
返回结果示例
+
{"status":true,"action":"onCodeResult","data":"@LogType(\"Arg\")\ncontract EventSuberAtCHQ{\n\t\n  \texport function init(arg){\n\t\tvar result \u003d YancloudUtil.subscribe(\"EventPuberAt3966\",\"abc\",handler);\n       // print(\"Handler:\"+handler);\n  \t \n  \t\treturn result;\n\t}\n  \texport function handler(e){\n        var ret \u003d \"ReceiveEvent:\";\n\t\tret+\u003d\"\\n\";\n      \tprint(ret);\n      \tret+\u003dYancloudUtil.executeContract(\"EventPuberAt3966\",\"notify\",\"success\");\n      \tprint(ret);\n        return ret;\n\t}\n}\n"}
+
+
+
+
+
+

保存合约状态

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondumpContract
contractID合约ID 或 合约Name=
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/SCManager?action=dumpContract&contractID=counter&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83
+
+
+
+
+
返回结果示例
+
{"data":"success","size":"3.76 KB","time":"0.03s"}
+
+
+
+
+
+

获取合约内存文件列表

+

向服务器发送请求, 获取某子文件夹中的所有内存文件列表.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistMemoryFiles
contractID合约Id 或 合约Name
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/SCManager?action=listMemoryFiles&contractID=-247468535&pubKey=040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f&sign=3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b
+
+
+
+
+
返回结果示例
+
{"data":["2020-09-23.18:40:38","2020-09-24.16:03:41","2020-09-24.16:58:39","2020-09-24.18:25:47","2020-09-24.18:32:37","2020-09-24.20:54:41","2020-09-24.20:57:39","2020-09-24.21:31:07","2020-09-24.21:32:09","2020-09-24.21:36:11","2020-09-28.15:29:15","2020-09-28.20:28:29","2020-09-28.20:39:46","2020-09-28.21:45:31","2020-09-28.21:49:18","2020-09-28.22:27:34","2020-09-28.22:31:09","2020-09-28.22:32:49","2020-10-07.16:51:06","2020-10-07.16:51:23","2020-10-25.21:09:10","2020-12-14.19:06:53","2021-02-02.10:28:56","2021-02-02.10:31:13"],"action":"onListMemoryFiles"}
+
+
+
+
+
+

停止合约

+

向服务器发送请求, 停止某个合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionkillContractProcess
id合约ID
*requestID请求ID, String类型

*表示可选参数

+
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=killContractProcess&id=-1759263594
+
+
+
+
+
返回结果示例
+
{"status":false,"action":"onListContractProcess","data":"[\n  {\n    \"id\": \"-65051856\",\n    \"name\": \"EventSuber\",\n    \"port\": \"1631\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"814046805\",\n    \"name\": \"EventSuberAtCHQ\",\n    \"port\": \"1630\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"2023975189\",\n    \"name\": \"LicenceService\",\n    \"port\": \"1632\",\n    \"times\": \"0 \",\n    \"traffic\": \"32.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  },\n  {\n    \"id\": \"-620602333\",\n    \"name\": \"shortc\",\n    \"port\": \"1627\",\n    \"times\": \"0 \",\n    \"traffic\": \"0.00 B\",\n    \"storage\": \"0.00 B\",\n    \"contractStatus\": \"Ready\"\n  }\n]"}
+
+
+
+
+
+

停止所有合约

+

向服务器发送请求, 停止服务器上启动的所有合约.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionkillAllContract
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=killAllContract
+
+
+
+
+
返回结果示例
+
{"status":false,"action":"onKillAllContract","data":"Kill:7357,7541,7548,7555,7584,7585,7591,7598,7609,7612,8440,8442,8444,8521,"}
+
+
+
+
+
+

静态分析合约

+

向服务器发送请求, 静态分析合约脚本.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionstaticVerifyContract
contractid合约ID
script请求ID, String类型
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=staticVerifyContract&contractid=943728900&script=contract%20shortc%7B%0A%09export%20function%20main(arg)%7B%0A%09%09return%20arg.length%3B%09%0A%09%7D%0A%7D&path=static.yjs
+
+
+
+
+
返回结果示例
+
{"data":"{\"status\":\"Success\",\"result\":\"{\\\"main\\\":\\\"Ret:arg \\\"}\"}","action":"onExecuteResult","cid":"943728900","executeTime":54}
+
+
+
+
+
+

获取合约静态分析流

+

向服务器发送请求, 获取某个合约的静态分析Control Flow.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiongetControlFlowByFileName
path合约ID
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=getControlFlowByFileName&path=EventSuber.yjs
+
+
+
+
+
返回结果示例
+
{"init":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","aload 4","invokedynamic dyn:getProp|getElem|getMethod:YancloudUtil (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B3","stmts":["dup","invokedynamic dyn:getMethod|getProp|getElem:subscribe (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B4","stmts":["swap","ldc XiaomiSmartHomeAtPKU","ldc onAirPurifierModeChange","aload 4","invokedynamic dyn:getProp|getElem|getMethod:handler (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B5","stmts":["invokedynamic dyn:call:\\\u003dYancloudUtil\\,subscribe (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B6","stmts":["\u003dL3\u003d","astore 5"],"original":"\t\tvar result \u003d YancloudUtil.subscribe(\"XiaomiSmartHomeAtPKU\",\"onAirPurifierModeChange\",handler);"},{"type":"Continuous","name":"B7","stmts":["\u003dL4\u003d","aload 5","areturn"],"original":"  \t\treturn result;"},{"type":"Continuous","name":"B8","stmts":["\u003dL5\u003d"],"original":"  \t\treturn result;"},{"type":"Continuous","name":"B9","stmts":["\u003dL6\u003d"],"original":"  \t\treturn result;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B9","label":{"label":"e"}}]},"handler":{"blocks":[{"type":"Continuous","name":"B0","stmts":["\u003dL0\u003d","aload 0","invokevirtual wrp/jdk/nashorn/internal/runtime/ScriptFunction getScope ()Lwrp/jdk/nashorn/internal/runtime/ScriptObject;"],"original":""},{"type":"Continuous","name":"B1","stmts":["\u003dL1\u003d","astore 4"],"original":""},{"type":"Continuous","name":"B2","stmts":["\u003dL2\u003d","ldc ReceiveEvent:","aload 2","invokedynamic dyn:getProp|getElem|getMethod:content (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B3","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B4","stmts":["ldc  ","invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B5","stmts":["aload 2","invokedynamic dyn:getProp|getElem|getMethod:type (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 0 "],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B6","stmts":["invokestatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime ADD (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B7","stmts":["\u003dL3\u003d","astore 5"],"original":"        var ret \u003d \"ReceiveEvent:\"+e.content+\" \"+e.type;"},{"type":"Continuous","name":"B8","stmts":["\u003dL4\u003d","aload 4","invokedynamic dyn:getMethod|getProp|getElem:print (Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B9","stmts":["getstatic wrp/jdk/nashorn/internal/runtime/ScriptRuntime UNDEFINED Lwrp/jdk/nashorn/internal/runtime/Undefined;","aload 5","invokedynamic dyn:call:print (Ljava/lang/Object;Lwrp/jdk/nashorn/internal/runtime/Undefined;Ljava/lang/Object;)Ljava/lang/Object; HANDLE:wrp/jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite; (6) 5 "],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B10","stmts":["pop"],"original":"      \tprint(ret);"},{"type":"Continuous","name":"B11","stmts":["\u003dL5\u003d","aload 5","areturn"],"original":"        return ret;"},{"type":"Continuous","name":"B12","stmts":["\u003dL6\u003d"],"original":"        return ret;"},{"type":"Continuous","name":"B13","stmts":["\u003dL7\u003d"],"original":"        return ret;"}],"edges":[{"from":"B0","to":"B1","label":{"label":"e"}},{"from":"B1","to":"B2","label":{"label":"e"}},{"from":"B2","to":"B3","label":{"label":"e"}},{"from":"B3","to":"B4","label":{"label":"e"}},{"from":"B4","to":"B5","label":{"label":"e"}},{"from":"B5","to":"B6","label":{"label":"e"}},{"from":"B6","to":"B7","label":{"label":"e"}},{"from":"B7","to":"B8","label":{"label":"e"}},{"from":"B8","to":"B9","label":{"label":"e"}},{"from":"B9","to":"B10","label":{"label":"e"}},{"from":"B10","to":"B11","label":{"label":"e"}},{"from":"B11","to":"B13","label":{"label":"e"}}]}}
+
+
+
+
+
+
+

日志查看类

+
+

合约日志-查询数量

+
+
方法
+

GET

+

contractName为空或是不传入时,则为查询全部合约的条数

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogSize
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogSize&contractName=NanningDataSource
+
+
+
+
+
返回结果示例
+
{
+    "size": 12,
+    "action": "onQueryContractLogSize",
+    "status": "success"
+}
+
+
+
+
+
+

合约日志-根据日期查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogByDate
startlong,必须,起始时间
endlong,非必须,若无end,默认为当前时间
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByDate&start=1597296300272&end=1597296305747
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getMainFrame",
+            "costTime": "2493",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296300272,
+            "key": "-8590335427581967208"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "732",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296301030,
+            "key": "849660532962309239"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4580",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305745,
+            "key": "-8003529429500512736"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4551",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305746,
+            "key": "7604666709899222357"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305751,
+            "key": "-7561786202695627022"
+        }
+    ],
+    "action": "onQueryRecentContractLog"
+}
+
+
+
+
+
+

合约日志-根据偏移量查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogByOffset
countlong,必须,获取日志条数
offsetlong,非必须,若无offset,默认返回最新count条
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByOffset&count=5&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "loadResource",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305842,
+            "key": "-2390672423847654148"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "isOwner",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305868,
+            "key": "6056586201629372511"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getApplyList",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305893,
+            "key": "3882409580676458151"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "getAcceptList",
+            "costTime": "4",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "date": 1597296305908,
+            "key": "-3437513873417136535"
+        },
+        {
+            "action": "executeContract",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "contractID": "-1382208250",
+            "contractName": "NanningDataSource",
+            "function": "analysisByIndustry",
+            "costTime": "6",
+            "totalGas": "0",
+            "executionGas": "0",
+            "extraGas": "0",
+            "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02",
+            "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}",
+            "date": 1597296314654,
+            "key": "203156239086062402"
+        }
+    ],
+    "action": "onQueryRecentContractLog"
+}
+
+
+
+
+
+

合约日志-根据key查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryContractLogByKey
keylong,必须,该日志对应的key
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryContractLogByKey&key=203156239086062402
+
+
+
+
+
返回结果
+
{
+    "data": {
+        "action": "executeContract",
+        "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+        "contractID": "-1382208250",
+        "contractName": "NanningDataSource",
+        "function": "analysisByIndustry",
+        "costTime": "6",
+        "totalGas": "0",
+        "executionGas": "0",
+        "extraGas": "0",
+        "signature": "4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02",
+        "arg": " {\"year\":2018,\"category\":\"工业\",\"indexType\":\"营业额\"}",
+        "date": 1597296314654
+    },
+    "action": "onQueryContractLogByKey"
+}
+
+
+
+
+
+

合约日志-按时间段统计调用次数

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actioncountContractLogGroupByCategory
startlong,必须,起始时间
end非必须,终止时间,默认为当前
intervallong,非必须,统计间隔
category非必须,合约名称以逗号连接,不传入时统计全部合约调用情况
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=countContractLogGroupByCategory&start=1596758400000&interval=86400000
+
+
+
+
+
返回结果
+
{
+    "start": 1596758400000,
+    "interval": 86400000,
+    "action": "onCountContractLogGroupByCategory",
+    "data": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        43,
+        14
+    ]
+}
+
+
+
+
+
+

账本日志-查询数量

+

查询通过本节点去账本上记录的日志数量

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryHashSize
contractName非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashSize&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "count": "2",
+    "action": "onQueryHashSize"
+}
+
+
+
+
+
+

账本日志-根据偏移量查询

+

查询x条通过本节点去账本上记录的日志的哈希列表

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryHashByOffset
count整数,必须,表示条数
offset整数,非必须,表示偏移量,不传入offset则默认返回最新count条
contractName字符串,非必须,表示合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryHashByOffset&count=1&contractName=NanningDataSource
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "hash": "3a6c60621907146b77146c1f2d48700e47520173",
+            "date": 1597296314658
+        }
+    ],
+    "action": "onQueryHash",
+    "status": "success"
+}
+
+
+
+
+
+

账本日志-根据hash查询详情

+

根据hash来查询日志内容

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryDataByHash
hash字符串,可通过queryHashByOffset
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryDataByHash&count=1&contractName=NanningDataSource&hash=3a6c60621907146b77146c1f2d48700e47520173
+
+
+
+
+
返回结果
+
{
+    "from": "0x3034643139323433323966373263656431343866",
+    "to": "0x65786563757465436f6e74726163740000000000",
+    "data": "1597296314655 --> {\"extraGas\":\"0\",\"totalGas\":\"0\",\"executionGas\":\"0\",\"signature\":\"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02\",\"costTime\":\"6\",\"arg\":\" {\\\\\\\"year\\\\\\\":2018,\\\\\\\"category\\\\\\\":\\\\\\\"工业\\\\\\\",\\\\\\\"indexType\\\\\\\":\\\\\\\"营业额\\\\\\\"}\",\"contractID\":\"-1382208250\",\"action\":\"analysisByIndustry\",\"pubKey\":\"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd\"}",
+    "requestID": "1597296314629_6067",
+    "action": "onQueryDataByHash"
+}
+
+
+
+
+
+

账本日志-根据requestID查询Hash

+

根据requestID来查询日志内容,需由开发者保证requestID的唯一性

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryHashByRequestID
requestID字符串,在发起调用时生成
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=queryHashByRequestID&requestID=0987654321ab
+
+
+
+
+
+

节点日志-查询数量

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryNodeLogSize
category非必须,不传入时查询全部情况

其中包括:ping、startContract、saveFile等。

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogSize&category=login
+
+
+
+
+
返回结果
+
{
+    "size": 177,
+    "action": "onQueryNodeLogSize",
+    "status": "success"
+}
+
+
+
+
+
+

节点日志-按日期查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryNodeLogByDate
startlong,必须,起始日期
endlong,非必须
category非必须,不传入时查询全部情况
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1597376006441
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByDate&start=1596758400000&category=login
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "listAllAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006438,
+            "key": "387355870552374748"
+        },
+        {
+            "action": "listUnAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006441,
+            "key": "4772693258708933626"
+        },
+        {
+            "action": "countRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006444,
+            "key": "-6425375229108830572"
+        },
+        {
+            "action": "loadNodeConfig",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006448,
+            "key": "-6602401010405792959"
+        },
+        {
+            "action": "getPeerID",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006449,
+            "key": "-7006776427870311552"
+        }
+    ],
+    "action": "onQueryNodeLogByDate"
+}
+
+
+
+
+
+

节点日志-按偏移量查询

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionqueryNodeLogByOffset
countlong,必须,获取日志条数
offsetlong,非必须,若无offset,默认返回最新count条
contractName字符串,非必须,合约名称
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=queryNodeLogByOffset&count=5
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "action": "listAllAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006438,
+            "key": "387355870552374748"
+        },
+        {
+            "action": "listUnAuthRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006441,
+            "key": "4772693258708933626"
+        },
+        {
+            "action": "countRole",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006444,
+            "key": "-6425375229108830572"
+        },
+        {
+            "action": "loadNodeConfig",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006448,
+            "key": "-6602401010405792959"
+        },
+        {
+            "action": "getPeerID",
+            "pubKey": "04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd",
+            "status": "accept",
+            "date": 1597376006449,
+            "key": "-7006776427870311552"
+        }
+    ],
+    "action": "onQueryNodeLogByOffset"
+}
+
+
+
+
+
+

节点日志-按时间段统计调用次数

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actioncountLogGroupByCategory
startlong,必须,起始时间
end非必须,终止时间,默认为当前
intervallong,非必须,统计间隔
category非必须,action以逗号连接,不传入时统计全部调用情况

其中,category中的action为NodePortal的接口的action集合。 +包括:ping、startContract、saveFile等。

+
+
+
请求示例
+
http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000
+
+http://127.0.0.1:18000/SCIDE/CMManager?action=countNodeLogGroupByCategory&start=1596758400000&interval=86400000&category=ping,startContract
+
+
+
+
+
返回结果
+
{
+    "start": 1596758400000,
+    "interval": 86400000,
+    "action": "onCountNodeLogGroupByCategory",
+    "data": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        912,
+        761
+    ]
+}
+
+
+
+
+
+

输出历史记录日志

+

向服务器发送请求, 获取节点服务器上合约的TimeTravel日志.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTimeTravelLog
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=printTimeTravelLog
+
+
+
+
+
返回结果示例
+
{"status":false,"data":"[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/aa_1572335939893.dyjs\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n[CMActions] memory dir \u003d /Users/oliveds/docs/SmartContract/contractExamples/memoryDumps/.\n"}
+
+
+
+
+
+

输出节点转移日志

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
方法
+

GET

+
+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTransferLog
+
+
请求示例
+
http://127.0.0.1:1717/SCIDE/SCManager?action=printTransferLog
+
+
+
+
+
返回结果示例
+
{"status":false,"data":""}
+
+
+
+
+
+
+

模板生成类

+
+
+
+

账本Http接口

+
type: google.api.Service
+config_version: 3
+
+http:
+  rules:
+    - selector: bdware.bdledger.api.Node.ClientVersion
+      get: /v0/node/version
+    - selector: bdware.bdledger.api.Ledger.CreateLedger
+      post: /v0/ledgers
+      body: "*"
+    - selector: bdware.bdledger.api.Ledger.GetLedgers
+      get: /v0/ledgers
+    - selector: bdware.bdledger.api.Ledger.SendTransaction
+      post: /v0/ledgers/{ledger}/transactions
+      body: "*"
+    - selector: bdware.bdledger.api.Query.GetBlockByHash
+      get: /v0/ledgers/{ledger}/block
+    - selector: bdware.bdledger.api.Query.GetBlocks
+      post: /v0/ledgers/{ledger}/blocks/query
+      body: "*"
+    - selector: bdware.bdledger.api.Query.CountBlocks
+      post: /v0/ledgers/{ledger}/blocks/count
+      body: "*"
+    - selector: bdware.bdledger.api.Query.GetRecentBlocks
+      get: /v0/ledgers/{ledger}/blocks/recent
+    - selector: bdware.bdledger.api.Query.GetTransactionByHash
+      get: /v0/ledgers/{ledger}/transaction
+    - selector: bdware.bdledger.api.Query.GetTransactionByBlockHashAndIndex
+      get: /v0/ledgers/{ledger}/block/transaction
+    - selector: bdware.bdledger.api.Query.GetTransactions
+      post: /v0/ledgers/{ledger}/transactions/query
+      body: "*"
+    - selector: bdware.bdledger.api.Query.CountTransactions
+      post: /v0/ledgers/{ledger}/transactions/count
+      body: "*"
+
+
+
+

Note

+

Request/Response data of bytes type should/will be encoded with +Base64.

+
+
+

Note

+

When using hash strings in URL, they need to be encoded with +encodeURIComponent.

+
+
+

账本信息类

+
+

Node.ClientVersion {#_node_clientversion}

+

Get BDLedger node version

+
GET http://{{IP}}:{{PORT}}/v0/node/version
+
+
+
+
返回示例
+
{
+  "version": "dev-210119.a88bf4eb"
+}
+
+
+
+
+
+

Ledger.CreateLedger {#_ledger_createledger}

+

Create a new ledger

+
POST http://{{IP}}:{{PORT}}/v0/ledgers
+
+
+
+
请求示例
+
{
+  "name": "test"
+}
+
+
+
+
+
返回示例
+
{
+  "ok": true
+}
+
+
+
+
+
+

Ledger.GetLedgers {#_ledger_getledgers}

+

Get all ledgers

+
GET http://{{IP}}:{{PORT}}/v0/ledgers
+
+
+
+
返回示例
+
{
+  "ledgers": [
+    "default",
+    "test"
+  ]
+}
+
+
+
+
+
+

Ledger.SendTransaction {#_ledger_sendtransaction}

+

Send a new transaction

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions
+
+
+
+
请求示例
+
{
+  "transaction": {
+    "type": 0,
+    "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+    "nonce": 52,
+    "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+  }
+}
+
+
+
+
+
返回示例
+
{
+  "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+}
+
+
+
+
+
+
+

查询类

+
+

Query.GetBlockByHash {#_query_getblockbyhash}

+

Get a block identified by its hash

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block?hash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D
+
+
+

hash has to be encoded with +encodeURIComponent

+
+
返回示例
+
{
+  "block": {
+    "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+    "creator": "",
+    "nonce": "0",
+    "parentHashes": [
+      "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+      "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+      "3XkwkuMBearq8uavN76Te7Zdpl8="
+    ],
+    "witnesses": [],
+    "timestamp": "1611038043",
+    "size": "0",
+    "transactionCount": 1,
+    "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+    "transactions": [
+      {
+        "blockHash": "",
+        "blockTimestamp": "0",
+        "index": 0,
+        "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+        "type": "RECORD",
+        "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+        "nonce": "0",
+        "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+        "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+      }
+    ],
+    "transactionHashes": [
+      "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+    ]
+  }
+}
+
+
+
+
+
+

Query.GetBlocks {#_query_getblocks}

+

Get blocks in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/query
+
+
+
enum IncludeTransactions {
+  NONE = 0; // Don't include transaction data
+  HASH = 1; // Include transactions hashes
+  FULL = 2; // Include full transactions
+}
+
+
+

Requirement: asciimath:[“start_timestamp”⇐”end_timestamp”]

+

If only end_timestamp is not specified, or +asciimath:[“end_timestamp”-“start_timestamp”>”query.maxDuration”], +then end_timestamp will be set to +asciimath:[“start_timestamp”+”query.maxDuration”].

+

If only start_timestamp is not specified, then start_timestamp +will be set to asciimath:[“end_timestamp”-“query.maxDuration”].

+

In all cases, start_timestamp will never be earlier than the +genesis block’s timestamp, and end_timestamp will never be later +than the current timestamp when the node process the query request.

+
+
请求示例
+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000,
+  "include_transactions": 0
+}
+
+
+
+
+
返回示例
+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [],
+      "transactionHashes": []
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+
请求示例2
+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000,
+  "include_transactions": 1
+}
+
+
+
+
+
返回示例2
+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [],
+      "transactionHashes": [
+        "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+      ]
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+

Request body 3.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000,
+  "include_transactions": 2
+}
+
+
+

Response 3.

+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [
+        {
+          "blockHash": "",
+          "blockTimestamp": "0",
+          "index": 0,
+          "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+          "type": "RECORD",
+          "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+          "nonce": "0",
+          "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+          "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+        }
+      ],
+      "transactionHashes": [
+        "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+      ]
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+
+

Query.CountBlocks {#_query_countblocks}

+

Count all blocks in a ledger, or blocks in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/count
+
+
+

Requirement: asciimath:[“start_timestamp”⇐”end_timestamp”]

+

If neither start_timestamp nor end_timestamp is specified, +then count all blocks in the specified ledger.

+

If only end_timestamp is not specified, then count all blocks with +timestamps later than start_timestamp.

+

If only start_timestamp is not specified, then count all blocks +with timestamps earlier than end_timestamp.

+

In all cases, start_timestamp will never be earlier than the +genesis block’s timestamp, and end_timestamp will never be later +than the current timestamp when the node process the query request.

+
+
请求示例
+
{}
+
+
+
+
+
返回示例
+
{
+  "count": "5",
+  "startTimestamp": "0",
+  "endTimestamp": "1611039957"
+}
+
+
+
+
+
请求示例2
+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000
+}
+
+
+
+
+
返回示例2
+
{
+  "count": "1",
+  "startTimestamp": "1611038000",
+  "endTimestamp": "1611039000"
+}
+
+
+
+
+
+

Query.GetRecentBlocks {#_query_getrecentblocks}

+

Get recent count blocks (Only support IncludeTransactions=NONE for +now)

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/recent?count=2
+
+
+
+
返回示例
+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [],
+      "transactionHashes": []
+    },
+    {
+      "hash": "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8=",
+        "8pZPR74OALIbps5XFb4dL/s0j0M="
+      ],
+      "witnesses": [],
+      "timestamp": "1610968019",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "LuxttCm/pSHVMOKF0sJExk+DJXc=",
+      "transactions": [],
+      "transactionHashes": []
+    }
+  ],
+  "startTimestamp": "1610968019",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+
+

Query.GetTransactionByHash {#_query_gettransactionbyhash}

+

Get a transaction identified by its hash

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/transaction?hash=VQBeA5Ee0Y5hqEileoQuYMHbOSE%3D
+
+
+

hash has to be encoded with +encodeURIComponent

+
+
+

返回示例

+
{
+  "transaction": {
+    "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+    "blockTimestamp": "1611038043",
+    "index": 0,
+    "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+    "type": "RECORD",
+    "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+    "nonce": "0",
+    "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+    "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+  }
+}
+
+
+
+
+

Query.GetTransactionByBlockHashAndIndex {#_query_gettransactionbyblockhashandindex}

+

Get a transaction identified by hash of the block it belongs to and its +index inside the block

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block/transaction?blockHash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D&index=0
+
+
+

blockHash has to be encoded with +encodeURIComponent

+
+
+

返回示例

+
{
+  "transaction": {
+    "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+    "blockTimestamp": "1611038043",
+    "index": 0,
+    "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+    "type": "RECORD",
+    "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+    "nonce": "0",
+    "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+    "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+  }
+}
+
+
+
+
+

Query.GetTransactions {#_query_gettransactions}

+

Get transactions in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/query
+
+
+

start_timestamp and end_timestamp follow the same requirements +and rules as in ???.

+
+
请求示例
+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000
+}
+
+
+
+
+
返回示例
+
{
+  "transactions": [
+    {
+      "blockHash": "",
+      "blockTimestamp": "0",
+      "index": 0,
+      "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "type": "RECORD",
+      "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+      "nonce": "0",
+      "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+      "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+
+

Query.CountTransactions {#_query_counttransactions}

+

Count all transactions in a ledger, or transactions in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/count
+
+
+

start_timestamp and end_timestamp follow the same requirements +and rules as in ???.

+
+
请求示例
+
{}
+
+
+
+
+
返回示例
+
{
+  "count": "4",
+  "startTimestamp": "0",
+  "endTimestamp": "1611039957"
+}
+
+
+
+
+
请求示例2
+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000
+}
+
+
+
+
+
返回示例2
+
{
+  "count": "1",
+  "startTimestamp": "1611038000",
+  "endTimestamp": "1611039000"
+}
+
+
+
+
+
+
+
+
+

合约节点WebSocket接口

+
+

用户管理类

+
+

获取Session

+

登录前获取session以便进行签名。

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetSessionID
+
+
请求示例
+
var req = {};
+req.action = "getSessionID";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+	"action": "onSessionID",
+	"session": "9782323_session"
+}
+
+
+
+
+
+

用户登录

+

用户进行公私钥身份验证

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlogin
+
+
请求示例
+
var loginParam = {};
+loginParam.pubKey = global.sm2Key.publicKey;
+loginParam.signature = sm2.doSignature(global.session,
+			global.sm2Key.privateKey);
+loginParam.action = "login";
+wssocket.send(JSON.stringify(loginParam));
+
+
+
+
+
返回结果
+
{
+	"action": "onLogin",
+	"data": "NodeManager,ContractProvider"
+}
+
+
+
+
+
+

申请角色

+

在节点管理员界面申请可以申请称为合约管理员(ContractInstanceManager)、合约使用者(ContractUser)、合约提供者(ContractProvider)

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionapplyNodeRole
role申请角色名称
+
+
请求示例
+
var param = {};
+param.action = "applyNodeRole";
+param.role = "ContractUser";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onApplyRole",
+	"data": "success"
+}
+
+{
+    "action":"onApplyRole",
+    "data":"already has!"
+}
+
+
+
+
+
+

授权角色

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionauthNodeRole
isAcceptbool类型,表示否授权
pubKey授权用户公钥
+
+
请求示例
+
var param = {};
+param.action = "authNodeRole";
+param.isAccept = true;
+param.pubKey = "xxxxx";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onAuthNodeRole",
+	"data": "success"
+}
+
+
+
+
+
+

删除用户角色

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondeleteRole
role删除角色名称
+
+
请求示例
+
var deleteInfo = {};
+deleteInfo.pubKey = global.authorizedUsers.[publicKey];
+deleteInfo.action = "deleteRole";
+deleteInfo.role="ContractUser";
+wssocket.send(JSON.stringify(deleteInfo));
+
+
+
+
+
返回结果
+
{
+	"action": "onDeleteRole",
+	"data": "success"
+}
+
+
+
+
+
+

查看授权用户列表

+

查看准入管理员当前组网中已经授权的节点管理员

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistAllAuthRole
+
+
请求示例
+
var param = {};
+param.action = "listAllAuthRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onListAllAuthRole",
+    "data":
+    {
+        "kv":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab",
+              "value":"NodeManager,ContractProvider,ContractUser,ContractInstanceManager"}],
+        "time":[{"key":"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab",
+                "value":"1617178709933"}]
+    }
+}
+
+
+
+
+
+

查看申请用户列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistUnAuthRole
+
+
请求示例
+
var param = {};
+param.action = "listUnAuthRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onListUnAuthRole",
+	 "kv": [{
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": "ContractProvider,ContractUser"
+    }],
+    "time": [{
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": "1587398989914"
+    }]
+}
+
+
+
+
+
参数(删除)
+ + + + + + + + + + + + + +
字段
actionqueryUserStat
+
+
请求示例
+
var param = {};
+param.action = "queryUserStat";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onQueryUserStat",
+	"userListCount": 3,
+	"applyListCount":0
+}
+
+
+
+
+
+
+

合约代码管理类

+
+

获取公共合约文件列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistProjects
+
+
请求示例
+
var request = {};
+request.action = "listProjects";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\",\"BiddingExample\",\"ContractExecutor\"]",
+    "executeTime":0,
+    "isPrivate":false
+}
+
+
+
+
+
+

获取私有合约文件列表

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionlistProjects
pubKey该用户的公钥
isPrivatetrue
+
+
请求示例
+
var request = {};
+request.action = "listProjects";
+request.pubKey = "global.sm2.publicKey";
+request.isPrivate=true;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+

获取合约实例

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistContractProcess
+
+
请求示例
+
var request = {};
+request.action = "listContractProcess";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "status":false,
+    "action":"onListContractProcess",
+    "data":"[{\"id\": \"1658407837\",\"name\": \"BDCoin\",\"port\": \"1617\"}]"
+}
+
+
+
+
+
+

启动合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstartContract
ownerpubkey
requestID当前时间
script脚本内容
signature签名
+
+
请求示例
+
request.action = "startContract";
+request.owner = global.sm2Key.publicKey;
+request.requestID = new Date().getTime() + "";
+request.script = global.projectScript;
+request.signature = sm2.doSignature("Algorithm|" + request.script + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey);
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":\"\",\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}",
+    "action":"onStartContract",
+    "cid":"-506393888",
+    "executeTime":2496,
+    "responseID":"1617206735696"
+}
+
+
+
+
+
+

启动可信集群合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstartContractP2PTrustfully
ownerpubkey
isPrivate当前时间
path脚本所在路径
signature签名
peersID可信执行集群中的节点peerID组成的数组
+
+
请求示例
+
var request = {};
+request.action = "startContractP2PTrustfully";
+request.peersID = ["3r729hf2ehf982","sjdfiwoehfwoi34","wnfnwoeifnwenef"];
+var project = "JsonTest";
+request.path = "/" + project + "/mainfest.json";
+request.isPrivate = false;
+request.signature = sm2.doSignature("Trusted|" + request.path + "|"
++ global.sm2Key.publicKey, global.sm2Key.privateKey);  //合约的签名
+request.resultcheck = $("#resultcheck")[0].value;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"status\":\"Success\",\"result\":\"\"}",
+    "action":"onStartContractP2PTrustfully",
+    "cid":"-1543583350",
+    "executeTime":1544
+}
+
+
+
+
+
+

分发合约项目

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiondistributeContract
peersID集群中节点peer
projectName合约名
isPrivate是否在私有目录
sponsorPeerID发起者ID
signature签名
+
+
请求示例
+
request.action = "distributeContract";
+request.peersID = peersID;
+request.projectName = global.projects[global.lastClickedProjectId];
+request.isPrivate = $("#privateDir-tab").hasClass("active"); 
+request.sponsorPeerID = global.peerID;
+request.signature = sm2.doSignature("DistributeContract|" + request.projectName + "|" + global.sm2Key.publicKey, global.sm2Key.privateKey);  
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+	"action":"onDistributeContract",
+	"progress":"100.00%"
+}
+
+
+
+
+
+

终止合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionkillContractProcess
id合约id
requestID请求ID
+
+
请求示例
+
request.action = "killContractProcess";
+request.id = contractid;
+request.requestID = new Date().getTime() + "";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data": "ContractHandler: exit in 3 seconds!",
+    "action": "onOutputStream"
+}
+
+
+
+
+
+

终止所有合约

+
+
参数
+ + + + + + + + + + + + + +
字段
actionkillAllContract
+
+
请求示例
+
request.action = "killAllContract";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+   	"status":false,
+   	"action":"onKillAllContract",
+   	"data":"Kill:7241,7245,"
+}
+
+
+
+
+
+

静态分析合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionstaticVerifyContract
owner用户私钥
isPartial是否是部分
contractidcontractid
script脚本内容
path合约文件名
+
+
请求示例
+
request.action = "staticVerifyContract";
+request.owner = global.sm2Key.privateKey
+request.isPartial = false;
+request.contractid = contractid;
+request.script = global.projectScript;
+request.path = global.projectName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"{\"needSeq\":false,\"seq\":0,\"status\":\"Success\",\"result\":{\"hello\":\"Ret:\"},\"isInsnLimit\":false,\"totalGas\":0,\"executionGas\":0,\"extraGas\":0,\"size\":0,\"eventRelated\":false}",
+    "action":"onStaticVerifyResult",
+    "cid":"verify",
+    "executeTime":83
+}
+
+
+
+
+
+

删除合约

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondeleteFile
filefileName
+
+
请求示例
+
request.action = "deleteFile";
+request.file = fileName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onDeleteFile",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

私有合约传至公共目录

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionchangePublic
pubkey用户公钥
fileNamefileName
+
+
请求示例
+
request.action = "changePublic";
+request.pubkey = pubkey;
+request.fileName = fileName;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onChangePublic",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

上传合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionUploadFile
isAppendfalse
fileNamefileName
pathpath
isPrivatetrue/false
contentfileContent(base64编码)
+
+
请求示例
+
request.action = "uploadFile";
+request.isAppend = false;
+request.fileName = "test1.yjs";
+request.path = "test1";
+text="Y29udHJhY3QgdGVzdDF7CglleHBvcnQgZnVuY3Rpb24gaGVsbG8oYXJnKXsgCiAgICAgICAgcmV0dXJuICJ3b3JsZCI7ICAKICAgIH0gICAKfQ=="
+request.content = text;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "action":"onUploadFile",
+    "data":"success",
+    "executeTime":0
+}
+
+
+
+
+
+

编译合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actioncompile
pathstring, 待编译的项目名称
privateTabbool, 是否为私有目录的项目
+
+
请求示例
+
var req = {"action":"compile","path":"Hello","privateTab":true}
+
+
+
+
+
返回结果
+
{"result":"Hello_2020-08-17-09:09:40.ypk","action":"onCompile"}
+
+
+
+
+
+

锁定私有目录

+

锁定某个用户的的私有目录编辑功能

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlockEdit
pubKeystring, 要被锁定的公钥
+
+
请求示例
+
var req = {};
+req.action = "lockEdit";
+req.pubKey = "xxxxxx";
+wssocket.send(JSON.stringify(req));
+
+
+
{
+    "action":"onLockEdit",
+    "status":"success",
+    "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1"
+}
+
+
+
+
+
+

解锁私有目录

+

解锁某个用户的的私有目录编辑功能

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionunLockEdit
pubKeystring, 要被锁定的公钥
+
+
请求示例
+
var req = {};
+req.action = unlockEdit;
+req.pubKey = "xxxxxx";
+wssocket.send(JSON.stringify(req));
+
+
+
{
+    "action":"onUnlockEdit",
+    "status":"success",
+    "data":"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1"
+}
+
+
+
+
+
+
+

合约实例管理类

+
+

查询合约进程

+

向服务器发送请求, 查询服务器上已经启动的所有合约进程.

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistContractProcess
+
+
请求示例
+
var request = {};
+request.action = "listContractProcess";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+	"status": false,
+	"action": "onListContractProcess",
+	"data": "[...]"
+}
+
+
+
+
+
+

调用合约

+

向服务器发送请求, 调用某个合约.

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actionexecuteContract
contractID合约ID
withDynamicAnalysistrue/false 是否进行动态分析,可选
operation调用合约的方法名
arg调用合约的参数
pubkey调用者公钥,可选
signature调用者签名 ,可选

*表示可选参数

+
//sm2 可从sm2.js中加载获得。
+signature = sm2.doSignature(contractID+"|"+operation+"|"+arg+"|"+pubkey,privateKey);
+
+
+
+
+
请求示例
+
var request = {};
+request.action = "executeContract";
+request.contractID = "2073401446";
+request.operation = "main";
+request.arg = "hhhhh";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "needSeq":false,
+    "seq":0,
+    "status":"Success",
+    "result":"world",
+    "isInsnLimit":false,
+    "totalGas":0,
+    "executionGas":0,
+    "extraGas":0,
+    "size":0,
+    "eventRelated":false,
+    "responseID":"1617211077264_223",
+    "action":"onExecuteResult",
+    "executeTime":"5"
+}
+
+
+
+
+
+

输出历史记录日志(删除)

+

向服务器发送请求, 获取节点服务器上合约的TimeTravel日志.

+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTimeTravelLog
+
+
请求示例
+
var request = {};
+request.action = "printTimeTravelLog";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+	"status": false,
+	"data": "[CMActions] dumpContract :…t/contractExamples/memoryDumps/LicenceManager\n"
+}
+
+
+
+
+
+

输出节点转移日志(删除)

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
参数
+ + + + + + + + + + + + + +
字段
actionprintTransferLog
+
+
请求示例
+
var request = {};
+request.action = "printTransferLog";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
 {
+	"status": false,
+	"data": ""
+}
+
+
+
+
+
+

合约状态迁移

+

向服务器发送请求, 获取节点服务器的状态转移日志.

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionloadMemory
contractName合约名称
memoryFile合约文件名称
+
+
请求示例
+
var request = {};
+request.action = "loadMemory";
+request.contractName = "JsonContract";
+request.memoryFile = "2020-03-17.20/42/55";
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果示例
+
{
+    "data":"success",
+    "size":"0.00 B",
+    "action":"onTransferTo",
+    "time":"0.01s"
+}
+
+
+
+
+
+
+

日志查看类

+
+

查看本地近n日节点日志(删除)

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistLocalNodeLog
date当前时间
+
+
请求示例
+
request.action = "listLocalNodeLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+   "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]"
+}
+
+
+
+
+
+

查看本地近n日合约日志(删除)

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistLocalContractLog
date当前时间
+
+
请求示例
+
request.action = "listLocalContractLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]"
+}
+
+
+
+
+
+
+

节点配置类

+
+

获取节点配置信息

+
+
参数
+ + + + + + + + + + + + + +
字段
actionloadNodeConfig
+
+
请求示例
+
var param = {};
+param.action = "loadNodeConfig";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onLoadNodeConfig",
+	"data": {
+		"nodeName": "04BF52213343C147E631B877BCEB17B794230EE551E85F58FA429C4BA03D690778CC384C6916C63DF36CB9E35C7E274FDB4E18491DFE3D611D347856D441CACC5AF9090B515F02AFC2DFBF56461EC83B5A4CD342466360D6CF82E6E40B637430AC4A329CCBC798DAF7D526AF9E3B3600E0BEA1BFAB8C160EF90128FAF67B19E45F37664F1E4B",
+		"licence": "04AADCC7103CD02626D228AFFBEF53F8242ECA4DDD6F179D30B622440666715CFBB6FD1D3678A2B25812DEA9917073E79A65F7ADE517F784DC76288EFCEB37ECAA1025E6903540702F729DA1C2ECCD93F4E6FAFCE40DF443E7FD74387169D0C6D927C7BB12882D0471C8D3E6F31B0316A42FC38F6DD9978D4351B23B2AD63E2244909E98F51185D32CB99B4AE4E22D3AB4C04027BB",
+		"expireTime": "Wed Aug 26 09:43:08 CST 2020",
+		"nodes": "[\"node1\",\"node2\",\"node3\"]",
+		"yjsPath": "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar",
+		"nodeCenter": "ws://127.0.0.1:1719/SCIDE/NodeCenter"
+	}
+}
+
+{ 
+    "status":true,
+    "action":"onLoadNodeConfig",
+    "data":{  
+        "nodeName":"Node_180",
+        "peerID":"",
+        "masterAddress":"39.104.201.40:21031",
+        "licence":"04AADCC7103C",
+        "doipConfig":"{\\"LHSProxyAddress\\":\\"http://39.104.201.40:21042/\\",\\"ownerHandle\\":\\"86.5000.470/dou.TEST\\",\\"certPath\\":\\"keys/dou.TEST.keystore\\",\\"certPassword\\":\\"123456\\",\\"repoID\\":\\"86.5000.470/doip.vcg9Mu1gSq_bdw\\",\\"listeners\\":\\"[{\\\\\\"url\\\\\\":\\\\\\"tcp://39.104.201.40:21032\\\\\\",\\\\\\"protocolVersion\\\\\\":\\\\\\"2.1\\\\\\",\\\\\\"messageFormat\\\\\\":\\\\\\"packet\\\\\\"}]\\",\\"serviceDescription\\":\\"test local Contract Repository\\",\\"serviceName\\":\\"ContractEngine021\\"}",
+        "clusterConnected":"false",
+        "nodePubKey":"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5",
+        "ipPort":"",
+        "bdledger":"39.108.56.240:18091,39.108.56.12:1809139.104.70.160:18091 47.98.247.70:18091 47.98.248.208:18091 39.104.77.165:18091 47.98.249.131:18091",
+        "yjsPath":"/data/bdwaas/bdcontract/yjs.jar",
+        "nodeCenter":"ws://39.104.201.21040/SCIDE/NodeCenter"
+    }
+}
+
+
+
+
+
+

修改节点配置

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actionupdateConfig
key要改的配置项
val要更改的目标值

其中,key的可选项包括:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
key的示val示例说明
yjsPath/User/xxx/cp/yjs.jar合约进程启动所需的jar
dataChain192.168.1.8:18090,182.173.2.3:18091账本节点的ip与端口
nodeCenterws://127.0.0.1:18002CenterPortal所在的ip/端口
nodeNameNode_180字符串类型
masterAddress192.168.3.2:18001该NodePortal节点的ip和的TCP端口

其中NodePortal的TCP端口为Node的http/ws端口号+1。

+
+
+
+

修改节点名称

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeNodeName
data新的节点名称
+
+
请求示例
+
var param = {};
+param.action = "changeNodeName";
+param.data = "NewNodeName";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeNodeName",
+	"data": true
+}
+
+
+
+
+
+

修改节点YJS路径

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeYJSPath
data节点服务器yjs.jar路径
+
+
请求示例
+
var param = {};
+param.action = "changeYJSPath";
+param.data = "/Users/xxx/docs/BDWareHttp/generatedlib/yjs.jar";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeYJSPath",
+	"data": true
+}
+
+
+
+
+
+

修改NodeCenter

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeNodeCenter
data节点服务器要连接的NodeCenterWebSocket路径
+
+
请求示例
+
var param = {};
+param.action = "changeNodeCenter";
+param.data = "ws://127.0.0.1:1719/SCIDE/NodeCenter";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeNodeCenter",
+	"data": true
+}
+
+
+
+
+
+

修改账本节点

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionchangeBDledger
data数链节点的IP:port,用","隔开
+
+
请求示例
+
var param = {};
+param.action = "changeBDledger";
+param.data = "39.108.56.240:18091,39.108.56.12:18091";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onChangeBDledger",
+	"data": true
+}
+
+
+
+
+
+

上传节点Licence

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionuploadLicence
data节点服务器的Licence内容
+
+
请求示例
+
var param = {};
+param.action = "uploadLicence";
+param.data = "04AADCC7103C";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onUploadLicence",
+	"data": true
+}
+
+
+
+
+
+

获取节点ID

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetNodeID
+
+
请求示例
+
var param = {};
+param.action = "getNodeID";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"status": true,
+	"action": "onGetNodeID",
+	"data": "0431…d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d"
+}
+
+
+
+
+
+

获取节点所在的可信执行集群

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongetNodeTrustUnits
data节点ID
msgHandler收到回复的回调函数, 可使用"建立连接"的msgHandler
ws节点所属的NodeCenter的WebSocket地址
+
+
请求示例
+
centerportalws = createWssocket("ws://127.0.0.1:1718/NodeCenterWS",function() {
+var param = {};
+param.action = "getNodeTrustUnits";
+param.data = "0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d";
+centerportalws.send(JSON.stringify(param));
+}, msgHandler);
+
+
+
+
+
返回结果
+
{
+	"data": [{
+		"key": "0475c7b061...65e55_4063665700873624164",
+		"value": "[\"04541429c11b094…40009b4f06d\"]"
+	}],
+	"action": "onGetNodeTrustUnits"
+}
+
+
+
+
+
+
+

模板生成类

+
+

获取合约模板列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetTemplateList
+
+
请求示例
+
req={};
+req.action = "getTemplateList";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "data": [
+        {
+            "formDesc": {
+                "dbPWD": {
+                    "label": "密码",
+                    "type": "input"
+                },
+                "contractName": {
+                    "label": "合约名称",
+                    "type": "input"
+                },
+                "accessPolicy": {
+                    "label": "访问控制策略",
+                    "type": "input",
+                    "option": [
+                        {
+                            "text": "无访问控制",
+                            "value": "NAC"
+                        },
+                        {
+                            "text": "直接访问控制",
+                            "value": "DAC"
+                        },
+                        {
+                            "text": "基于角色的访问控制",
+                            "value": "RBAC"
+                        }
+                    ]
+                },
+                "dbUserName": {
+                    "label": "用户名",
+                    "type": "input"
+                },
+                "fieldList": {
+                    "label": "字段名",
+                    "type": "tag"
+                },
+                "dbUrl": {
+                    "label": "数据库链接",
+                    "type": "input"
+                },
+                "tableName": {
+                    "label": "表名",
+                    "type": "input"
+                }
+            },
+            "apiName": "generateMySQLProject"
+        },
+        {
+            "formDesc": {
+                "contractName": {
+                    "label": "合约名称",
+                    "type": "input"
+                },
+                "accessPolicy": {
+                    "label": "访问控制策略",
+                    "type": "input",
+                    "option": [
+                        {
+                            "text": "无访问控制",
+                            "value": "NAC"
+                        },
+                        {
+                            "text": "直接访问控制",
+                            "value": "DAC"
+                        },
+                        {
+                            "text": "基于角色的访问控制",
+                            "value": "RBAC"
+                        }
+                    ]
+                }
+            },
+            "apiName": "generateEmptyProject"
+        }
+    ],
+    "action": "onTemplateList"
+}
+
+
+
+
+
+

空白合约模板

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongenerateEmptyProject
contractName字符串类型,合约名称
isPrivate布尔类型,是否为私有项目
accessPolicy若为"DAC",则实现直接访问控制
+
+
请求示例
+
var req = {};
+req.contractName = "Empty22";
+req.action = "generateEmptyProject";
+req.accessPolicy = "DAC";
+//wssocket为建立好的连接
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"AnnotationSample\",\"AppDataAnalysis\",\"AppDataSource\"]",
+    "executeTime":0,
+    "isPrivate":false
+}
+
+
+
+
+
+

MySQL接入合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongenerateMySQLProject
contractName字符串类型,合约名称
isPrivate布尔类型,是否为私有项目
dbUrl字符串类型,数据库的URI
dbUserName字符串类型,数据库的用户名
dbPWD字符串类型,数据库密码
accessPolicy若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制
tableName字符串类型,数据库的表名
fieldList字符串列表,数据库的字段列表
defaultAccept布尔值,表示申请时是否默认有权
+
+
请求示例
+
var req = {};
+req.contractName = "MySQLFromTemplate";
+req.action = "generateMySQLProject";
+req.pubKey = global.sm2Key.publicKey;
+req.isPrivate = true;
+req.tableName = "data";
+req.dbUrl = "jdbc:mysql://xxx:xxx/xxx";
+req.dbUserName = "loushuai";
+req.dbPWD = "loushuai";
+req.fieldList = [{"name":"名字","code":"*"}];
+req.basicInfo={"type":"所属分类","name":"资源名称"};
+req.accessPolicy = "DAC";
+req.defaultAccept = true;
+//global.wssocket为建立好的连接
+global.wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+

CSV接入合约

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字段
actiongenerateCSVProject
contractName字符串类型,合约名称
base64EncodedData字符串类型,通过base64编码后的CSV文件内容
isPrivate可选字段,布尔类型,是否为私有项目
accessPolicy若为"DAC",则实现直接访问控制,若为"NAC"则没有访问控制
defaultAccept可选字段,布尔值,表示申请时是否默认有权
+
+
请求示例
+
var req = {};
+req.contractName = "CSVFromTemplate";
+req.action = "generateCSVProject";
+req.pubKey = global.sm2Key.publicKey;
+req.isPrivate = true;
+req.tableName = "data";
+req.accessPolicy = "DAC";
+req.defaultAccept = true;
+req.base64EncodedData = "bmFtZSwgc2NvcmUsCmphY2ssIDkwLApsdWN5LCA5MQo=";
+//global.wssocket为建立好的连接
+global.wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+    "action":"onListProjects",
+    "data":"[\"CSVFromTemplate\",\"Empty22\",\"Hello\",\"MySQLFromTemplate\",\"test\"]",
+    "executeTime":0,
+    "isPrivate":true
+}
+
+
+
+
+
+
+
+
+

路由节点WebSocket接口

+
+

用户管理类

+
+

获取Session

+

登录前获取session以便进行签名。

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetSessionID
+
+
请求示例
+
var req = {};
+req.action = "getSessionID";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+
返回结果
+
{
+	"action": "onSessionID",
+	"session": "9782323_session"
+}
+
+
+
+
+
+

用户登录

+

用户进行公私钥身份验证,需先调用”getSessionID”获取sessionID以便于签名。

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlogin
+
+
请求示例
+
var loginParam = {};
+loginParam.pubKey = global.sm2Key.publicKey;
+loginParam.signature = sm2.doSignature(global.session,
+			global.sm2Key.privateKey);
+loginParam.action = "login";
+wssocket.send(JSON.stringify(loginParam));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onLogin",
+	"data": "CenterManager"
+}
+
+
+
+
+
+

用户获取当前角色(删除)

+

用户根据登录时的公钥获取对应的角色,如果是第一次登录则此时的公钥默认称为准入管理员

+
+
参数
+ + + + + + + + + + + + + +
字段
actiongetRole
+
+
请求示例
+
var param = {};
+param.action = "getRole";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onGetRole",
+	"data": "CenterManager"
+}
+
+
+
+
+
+

申请角色

+

在准入管理员界面可以申请称为组网中某个节点的节点管理员

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionapplyRole
role申请的角色名称
+
+
请求示例
+
var param = {};
+param.action = "applyRole";
+param.role="
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onApplyRole",
+	"data": "failed"
+}
+
+
+
+
+
+

添加节点

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionaddNode
nodePubKey要添加的节点公钥
+
+
+

请求示例

+
var req = {};
+//某节点的publicKey可通过连接该节点,并通过"获取节点配置信息"接口获取
+req.nodePubKey = publicKey;
+req.action = "addNode";
+wssocket.send(JSON.stringify(req));
+
+
+
+
+

删除用户角色

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondelete
pubKey对应用户的公钥
+
+
请求示例
+
var deleteInfo = {};
+deleteInfo.pubKey = user.publicKey;
+deleteInfo.action = "delete";
+wssocket.send(JSON.stringify(deleteInfo));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onDelete",
+	"data": "success"
+}
+
+
+
+
+
+

查看授权用户列表

+

查看准入管理员当前组网中已经授权的节点管理员

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistAllUsers
+
+
请求示例
+
var param = {};
+param.action = "onListAllUsers";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onListAllUsers",
+	 "kv": {
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": " NodeManager"
+    },
+    "time": {
+        "key": "049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7",
+        "value": 1587398989914
+    }
+}
+
+
+
+
+
+

查看申请用户列表

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistApplyList
+
+
请求示例
+
var param = {};
+param.action = "onListApplyList";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onListApplyList",
+	 "kv": {
+        "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7",
+        "value": " NodeManager"
+    },
+    "time": {
+        "key": "04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7",
+        "value": 1587398989914
+    }
+}
+
+
+
+
+
+

查看用户类型分布

+
+
参数
+ + + + + + + + + + + + + +
字段
actionqueryUserStat
+
+
请求示例
+
var param = {};
+param.action = "onQueryUserStat";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果示例
+
{
+	"action": "onQueryUserStat",
+	"userListCount": 3,
+	"applyListCount":0
+}
+
+
+
+
+
+
+

节点管理类

+
+

查看节点列表

+

查看该用户有权限查看的节点列表(仅准入管理员及合约管理者可用)

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistNodes
+
+
请求示例
+
var param = {};
+param.action = "listNodes";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"offline": [{
+		"key": "0431e31...40009b4f06d",
+		"value": "0431e311bd708...b4f06d"
+	}],
+	"action": "onListNodes",
+	"online": [{
+		"contracts": [],
+		"pubKey": "0431e311...09b4f06d",
+		"nodeName": "NewNodeName",
+		"udpID": "528822126",
+		"cimanager": ""
+	}]
+}
+
+
+
+
+
+

查看可信执行集群列表

+

查看该用户有权限查看的节点列表(仅中心管理员及合约管理者可用)

+
+
参数
+ + + + + + + + + + + + + +
字段
actionlistTrustUnits
+
+
请求示例
+
var param = {};
+param.action = "listTrustUnits";
+wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"data": [{
+		"key": "0470b2f27f4f6…1cb855f1ecec11",
+		"value": "[...]"
+	}],
+	"action": "onListTrustUnits"
+}
+
+
+
+
+
+

建立可信执行集群

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + +
字段
actioncreateTrustUnit
data节点公钥组成的Json数组
Msg集群名称
+
+
请求示例
+
var param = {};
+param.action = "createTrustUnit";
+param.data = "[\"382r0934309t...\",\"345343rr3f34...\"]";
+param.msg = "newUnit1";
+global.wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onCreateTrustUnit",
+	"status": "Success"
+}
+
+
+
+
+
+

删除可信执行集群

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actiondeleteTrustUnit
data可信执行集群ID
+
+
请求示例
+
var param = {};
+param.action = "deleteTrustUnit";
+param.data = "0475d34rf3434..._1583410158761";
+global.wssocket.send(JSON.stringify(param));
+
+
+
+
+
返回结果
+
{
+	"action": "onDeleteTrustUnit",
+	"status": "Success"
+}
+
+
+
+
+
+
+

日志查看类

+
+

查看组网管理操作的统计

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionqueryActionLog
date当前时间
+
+
请求示例
+
request.action = "onQueryActionLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{	"action":"onQueryActionLog",
+     "data":"[{\"action\":\"login\",\"pubKey\":\"null\",\"status\":\"accept\",\"date\":1583139323822}\",]"
+}
+
+
+
+
+
+

查看本地近n日合约日志

+
+
参数
+ + + + + + + + + + + + + + + + + +
字段
actionlistLocalContractLog
date当前时间
+
+
请求示例
+
request.action = "listLocalContractLog";
+request.date = new Date().getTime() - 24 * 3600 * 1000 * n;
+wssocket.send(JSON.stringify(request));
+
+
+
+
+
返回结果
+
{
+    "data":"[\"{\"action\":\"startContract\",\"pubKey\":\"04405d7b...\",\"contractID\":\"845581788\",\"contractName\":\"null\",\"date\":1583141525539}\"]"
+}
+
+
+
+
+
+
+
+
+

Bash接口

+

已废弃。可使用BDWareConfigTool代替。 +通过命令行发送Socket指令, 执行调用ContractController类中方法, 完成以下功能. (需要在本机的1615端口运行ContractManager实例)

+

Bash接口功能示意图

+
+

指令

+
java -jar yjs.jar function_name arguments
+
+
+

function_name为调用的方法名;

+

arguments为方法参数.

+
+
+

启动合约

+
+

参数

+

function_namestartContract;

+

arguments为启动合约需要的参数, 包括合约类型type, 合约IDid, 合约脚本script.

+
+
+

指令示例

+
java -jar yjs.jar startContract "{\"type\":\"Algorigthm\",\"id\":\"656565\",\"script\":\"contract c{function main(arg){return arg/1.0+1;}}\"}"
+
+
+
+
+
+

调用合约

+
+

参数

+

function_nameexecuteContract;

+

arguments为调用合约需要的参数, 包括调用参数arg, 合约IDcontractID.

+
+
+

指令示例

+
java -jar yjs.jar executeContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}"
+
+
+
+
+
+

停止合约

+
+

参数

+

function_namestopContract;

+

arguments为调用合约需要的参数, 即合约IDcontractID.

+
+
+

指令示例

+
java -jar yjs.jar stopContract "{\"arg\":\"http://www.baidu.com\",\"contractID\":\"656564\"}"
+
+
+
+
+
+

停止全部合约

+
+

参数

+

function_namestopAllContracts.

+
+
+

指令示例

+
java -jar yjs.jar stopAllContracts 
+
+
+
+
+
+

查询全部合约

+
+

参数

+

function_namelistContracts.

+
+
+

指令示例

+
java -jar yjs.jar listContracts 
+
+
+
+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/IDEUsage.html b/doc/markdown_BDWare/IDEUsage.html new file mode 100644 index 0000000..1c1be8b --- /dev/null +++ b/doc/markdown_BDWare/IDEUsage.html @@ -0,0 +1,614 @@ + + + + + + + + + + 管理界面 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

管理界面

+
+
+

合约节点管理界面

+

该界面的使用地址为:NodePortal.html

+
+

用户管理菜单

+

用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。

+
+

概览

+

nodeUserManager +节点用户管理页面一共有四个模块:用户情况、用户活跃统计、授权用户管理、未授权用户管理。

+
+
+

用户类型分布

+

主要统计当前节点管理员所拥有的四种角色的数量:合约提供者、合约管理员、合约使用者 +userList

+
+
+

用户活跃统计

+

userActive +统计30天之内登录授权申请的次数

+
+
+

当前用户信息

+

nodeInfo

+
    +
  • 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录节点管理员界面,可以将自己的公私钥复制到这个文本框中。

  • +
  • 将自己的公私钥复制完成之后要点击导入公钥,将公钥加入到节点管理员本地

  • +
  • 然后在本地公钥中可以看见公钥的前五位,选择自己的公钥,将在我的权限中展示出当前选择的公钥的角色,如果是还没有在中心管理员认证的节点则默认为Anonymous

  • +
  • 如果不是节点管理员,想要加入某个中心管理员的网络,那么要在中心管理员所在的用户管理中用自己的公私钥导入后进行认证。

  • +
  • 如果想要行使更多关于合约的操作,则需要认证不同的角色:合约管理员、合约使用者、合约提供者,然后进行角色认证

  • +
+
+
+

授权与非授权用户列表

+

roleAuth +在节点管理员认证角色之后,节点管理员登录会在未授权角色管理表格中看见带有公钥的申请信息,如果同意,则点击授权,如果不同意点击忽略就可以。 +授权之后将在授权角色管理表格中看见授权后的节点列表。如果节点管理员想要移除某个节点的角色,则在授权角色管理列表中删除即可。

+
+
+
+

合约代码管理菜单

+

codeManageMenu

+
+

合约文件

+

codeManage1

+

在合约代码管理菜单中,用户可以看到公共合约以及个人私有合约。 +codeManage1-1

+

对于公共合约,节点管理员可以对其中文件进行删除和上传操作,可以对合约项目进行下载和删除操作。 +codeManage1-2

+

对于私有合约,合约提供者可以对其中文件进行删除和上传操作,可以对合约项目进行下载、删除和传至公共合约目录操作。

+

以下是对合约文件进行操作的示例。

+
+
+

上传文件

+

codeManage6

+
+
+

删除

+

codeManage5

+
+
+

传至公共

+

codeManage7

+
+
+

下拉框

+

codeManage2

+

四个下拉框中,可以分别对合约状态保存模式、已启动合约实例、节点所在集群以及结果校验方式进行选择。

+
+
+

按钮操作

+

codeManage3

+
+
+

启动

+

在文件列表中选择合约文件之后,在合约运行模式中选择“单节点执行”,点击启动按钮,会启动指定文件,并在结果显示框中显示返回结果。

+
+
+

启动P2P集群合约

+

在文件列表中选择合约文件之后,在合约运行模式中选择该可信合约运行的合约集群,点击启动按钮,会在该集群的所有节点上启动指定文件,并在结果显示框中显示返回结果。

+
+
+

启动全部

+

在合约运行模式中选择“单节点执行”,点击启动全部按钮,会启动合约文件列表中所有合约。

+
+
+

停止P2P集群合约

+

在已启动合约实例的下拉框中选择一个合约实例,在合约运行模式中选择该可信合约运行的合约集群,点击停止按钮,会在该集群的所有节点上终止这个合约进程。

+
+
+

停止

+

在已启动合约实例的下拉框中选择一个合约实例,点击停止按钮,会终止这个合约进程。

+
+
+

停止全部

+

点击停止全部按钮,会停止该节点上运行的所有合约实例。

+
+
+

静态分析

+

在合约文件列表中选择合约文件,并在合约实例下拉框中选择合约实例,点击静态分析按钮,会对该合约进行静态分析,并在结果显示框中显示返回结果。

+
+
+

分发合约

+

在合约文件列表中选择合约项目,并在合约运行模式中选择一个集群,点击分发合约按钮,会将该合约项目打包为ypk分发给这个集群中的所有节点。

+
+
+

返回结果

+

codeManage4

+

返回结果显示中显示一些操作的返回结果。

+
+
+

合约权限配置

+

在启动合约之后,如果当前用户的角色可以查看已经启动合约进程,那么在选定查看合约进程时将会在右下方展示当前合约的IO权限。 +permissionShow

+

如果选中的合约没有IO权限,则在当前权限的展示框中提示当前合约没有IO权限 +nullPermission

+

当前用户是合约管理员时可以对已有的合约IO权限进行修改。系统会提示修改后合约将有可能不会正常运行,如果还是确定要取消,那么点击确定 即可,反之点击关闭 +updatePermission

+

点击关闭或者打开之后,下一次查看同一个合约代码的进程将会默认显示最近一次修改之后的IO权限。 +closePermission

+
+
+
+

合约实例管理菜单

+

nodeInstancesPage

+

合约实例管理菜单显示了该节点当前的所有合约实例, 用户可查看合约实例的状态, 并对合约实例进行执行或状态迁移的操作.

+
+

合约实例列表

+

nodeInstancesList

+

该列表显示了当前节点的所有合约实例信息, 包括合约ID, 合约名称, 合约类型合约状态, 合约进程端口, 合约调用次数, 合约流量, 及合约占用内存, 集群合约的结果校验模式.

+
+
+

合约实例执行

+

chooseInstance

+

用户可在合约实例的选择下拉框中选择合约实例, 对该合约实例进行操作.

+

intanceExecute

+

选择合约实例后, 用户可在”方法”的下拉框中选择该合约的方法名, 在”参数”输入框中输入方法的参数, 点击”执行”.

+

用户还可点击”动态分析执行”进行带有动态分析结果的执行.

+

若该合约为单点合约, 则合约在单点执行; 若该合约为集群合约, 则该合约在该集群的所有节点上执行.

+
+
+

合约实例执行结果

+

executeResult

+

合约实例的执行完成后的结果显示在”执行结果”区域中, 包括该次执行的ID, 执行成功/失败, 执行时间, 及执行结果.

+

analysisExecuteResult

+

若该合约的执行方式为”动态分析执行”, 则结果框内除执行结果, 还会显示该次执行的动态分析结果.

+
+
+

合约状态迁移

+

memoryDump

+

对于支持用户手动迁移的合约实例, 用户可点击”本地状态保存”对合约实例的状态进行保存, 或从合约的TimeTravel列表中选择已保存的合约实例, 将合约状态迁移到对应时刻.

+
+
+
+

日志管理菜单

+

logMenu

+

该菜单是对该节点本地节点日志以及合约日志的统计结果展示。

+

其中,节点管理员可以查看节点日志的相关数据;合约管理者及合约使用者可以查看该节点本地合约日志的相关数据。

+
+

日志统计图

+

log1

+
+
+

各类平台操作百分比

+

该图默认显示近2日各类平台操作占比的饼图,其中平台操作分为登陆类、用户类、日志类、合约类、维护类以及其他类这六类。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比会同步更新。

+
+
+

各类合约操作百分比

+

合约操作分为启动、终止、静态分析和执行这四类,该图为近2日对各类合约操作占比的饼图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比会同步更新。

+
+
+

每日平台使用统计

+

该图为近2日平台操作次数统计的折线图。可在节点日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日平台使用统计折线图会同步更新。

+
+
+

每日合约使用统计

+

该图为近2日对该节点上合约的操作次数统计的折线图。可在合约日志详情的右上角的时间范围框中填写想要查看的日志时间范围,修改之后,每日合约使用统计折线图会同步更新。

+
+
+

日志详情

+
+
+

节点日志详情

+

log2

+

节点日志详情表是对节点日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类平台操作百分比和每日平台使用统计会同步更新。

+
+
+

合约日志详情

+

log3

+

合约日志详情表是对合约日志中所有数据的展示。可以点击表格中相关按钮按使得日志数据按不同方式进行排序,并且可以在表格右上角输入关键词进行相关日志搜索。可在右上角的时间范围框中填写想要查看的日志时间范围,修改之后,各类合约操作百分比和每日合约使用统计会同步更新。

+
+
+
+

节点管理菜单

+

nodeConfig

+

节点管理菜单显示了该节点的配置信息及所属可信执行集群信息.

+
+

节点配置

+

nodeConfigChange

+

节点管理员可查看该节点的配置信息, 包括节点名称, 节点YJS路径, 节点的网络中心节点, 节点管理员还可对以上配置进行修改.

+

若节点管理员修改了节点的网络中心, 该节点后重新想改节点连接, 整个页面刷新重载.

+
+
+

节点可信执行集群列表

+

nodeUnits

+

节点管理员可查看节点所属的可信执行集群信息, 包括集群创建者, 集群ID, 集群中节点数目, 集群中节点的信息.

+
+
+
+

节点Licence配置

+

nodeLicence

+

用户可以查看该节点的Licence及过期时间, 还可申请Licence, 上传Licence, 保存节点UUID.

+
+
+
+
+

智能合约在线编辑器

+
+

用户与账号

+
+

创建账号

+
+
+

申请授权

+
+
+
+

创建项目

+
+

新建文件

+
+
+

上传文件

+
+
+
+

启动合约

+

contractMode

+

####正常模式 +点击左侧启动按钮,以正常模式启动合约。

+

####debug模式 +点击右侧debug按钮,以debug模式启动合约。目前约定debug模式合约通过executeContract调用正常模式合约时,返回正常模式合约文档中的返回结果示例。

+
+
+

调用合约

+

###生成文档 +genReadme

+

启动合约后点击”生成文档”按钮,可以通过各export函数的@Description / @Param / @Result 对合约进行调用及结果返回,从而生成合约的说明文档。

+
+
+
+
+

路由准入管理界面

+
+

权限申请与授权

+
+
+

仪表盘

+

仪表盘为提供对准入节点中用户数量,合约数量,节点数量的概览。

+
+
+

整体视图

+

dashboard +一共分为四个模块,一个模块是用户、合约、节点数量的概览,然后分别是这三个数量的详细分类的数据统计情况。

+
+
+

节点数目

+

node +当前在线和离线节点统计

+
+
+

用户类型分布

+

userAll +当前准入节点所在组网中的节点管理员、准入管理员的数量和申请中节点的数量

+
+
+

合约调用情况

+

contract +当前准入节点所在组网中所有合约中事件、多点执行、ws调用、Http调用的折线统计图。

+
+
+

用户管理

+

用户管理为登录用户提供查看当前用户分布情况和用户活跃情况统计等。

+
+
+

概览

+

centerManager +用户管理页面一共有四个模块。

+
+
+

用户类型分布

+

主要统计当前中心管理员所管理的网络中有多少节点管理员,多少个中心管理以及申请节点管理员的数量 +userList

+
+
+

30天内的申请情况统计

+

userApplyGraph +统计30天之内申请节点管理员的数量和授权成为节点管理员的数量

+
+
+

当前用户信息

+

authNodeManager

+
    +
  • 在这个文本框中可以查看当前用户的公私钥,如果其他用户想要用自己的公私钥登录中心管理员界面,可以将自己的公私钥复制到这个文本框中。

  • +
  • 将自己的公私钥复制完成之后要点击导入公钥,将公钥加入到中心管理员本地

  • +
  • 然后在本地公钥中可以看见公钥的前五位,选择自己的公钥,将在我的权限中展示出当前选择的公钥的角色,如果是中心管理员则拥有中心管理员的一切权限。

  • +
  • 如果不是中心管理员或者节点管理员,想要加入当前中心管理员的网络,那么可以在下面的选择框中选中节点管理员,进行角色认证

  • +
+
+
+

授权与非授权用户列表

+

在中心管理员当前用户信息申请之后,中心管理员登录会在未授权用户管理表格中看见带有公钥的申请信息,如果同意,则点击授权,如果不同意点击忽略就可以,此时这个申请就无效。 +authMan +授权之后将在授权用户管理表格中看见授权后的节点列表。如果中心管理员想要移除某个节点管理员的某项角色,则在授权用户管理列表中选择相应的角色,然后点击删除即可删除选中的角色。 +authMana

+
+
+

节点管理

+

centerNodePage

+

节点管理为Manager对连接到自己的Cluster节点进行管理的页面, 仅Manager管理员及合约管理者可见. Manager管理员及合约管理者可在本页面查看节点信息, 并管理可信执行集群.

+
+
+

概览

+

centerNodePreview

+

概览中显示了该Manager节点所管理的所有节点的统计信息, 包括总节点数量, 总合约数量, 总订阅事件数量, 及可信执行集群数量, 右侧的饼图则为节点的分别处于Online/Offline的数量统计.

+
+
+

节点列表

+

centerNodeList

+

节点列表显示了用户有权限查看的节点信息(Manager管理员可查看全部节点, 合约管理者可查看自己负责管理的Online节点). 包括节点的名称, 状态, 合约数目, 订阅事件数目, 用于节点间P2P通信的PeerID, 用于节点间UDP通信的UDPID, 及节点公钥.

+
+
+

可信执行集群列表

+

centerNodeUnits

+

可信执行集群列表显示了用户有权限查看的可信执行集群信息(Manager管理员可查看全部集群, 合约管理者可查看自己创建的集群). 包括集群的创建者, 集群ID, 集群中节点数目, 以及集群中节点的信息.

+

用户可点击列表表项的”删除”按钮, 将该集群删除.

+
+
+

创建可信执行集群

+

centerNodeUnitCreate

+

用户可以通过多选节点, 创建新的可信执行集群. 用户可以选择的节点为自己有权限查看的节点, 即Manager管理员从全部节点中选择, 合约管理者可从自己负责管理的Online节点中选择). 选择后点击提交, 即可看到创建成功的提示信息, 该集群将随即显示在可信执行集群列表中. 集群名称由创建者选取, 不能含有双引号, 该名称为合约管理者选择集群时的可见标识.

+
+
+

日志管理

+

日志管理主要展示准入节点的各项日志信息,一共分为六个模块。

+
+
+

概览

+

log

+
+
+

管理操作分类统计(2日)

+

operator +两日内所有管理类操作的统计饼图,管理类操作主要分为登录类、日志类、维护类、用户类。

+
+
+

管理操作每日统计(2日)

+

everyLog +两日内管理类所有的操作每日操作统计

+
+
+

合约操作分类统计(2日)

+

contractLog +两日内合约操作分类统计饼图,合约操作主要分为连接类和状态更新类。

+
+
+

合约操作每日统计(2日)

+

contracteveryLog +两日内合约操作数量折线统计图。

+
+
+

管理操作日志列表

+

opList +管理操作日志的详细信息列表。包括日志时间,管理操作名称,操作对应的节点公钥。默认展示范围是两天,可以自定义获取日志的天数。

+
+
+

合约操作日志列表

+

contractList +合约操作日志详细信息列表。包括日志产生时间,合约操作名称,合约操作节点公钥。默认展示范围是两天,可以自定义获取日志的天数。

+
+
+

设置

+

设置页面是节点证书的状态展示以及配置节点证书

+
+
+

概览

+

set

+
+
+

证书状态

+

licence +证书状态主要包括许可到期时间和许可节点数量。

+
+
+

配置证书

+

plicence +配置证书模块可以下载节点ID文件或者输入证书信息进行提交。

+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/InstallTips.html b/doc/markdown_BDWare/InstallTips.html new file mode 100644 index 0000000..7c26659 --- /dev/null +++ b/doc/markdown_BDWare/InstallTips.html @@ -0,0 +1,367 @@ + + + + + + + + + + 安装说明 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

安装说明

+
+
+

依赖环境的安装

+

1.安装Java1.8环境。

+

例如,在Ubuntu下使用apt-get进行安装:

+
apt-get install openjdk-8-jre
+
+
+

在Centos环境下,使用yum进行安装:

+
yum install java-1.8.0-openjdk
+
+
+

如果是离线环境,可先下载openjdk的安装包后进行离线安装。

+

Ubuntu下

+
dpkg -i jdk-8uxxxxx.deb
+
+
+

在Centos环境下,使用yum进行离线安装:

+
yum localinstall jdk-8u271-linux-xxx.rpm
+
+
+

2.安装wget与unzip。 +例如,在Ubuntu下使用apt-get进行安装:

+
apt-get install unzip
+apt-get install wget
+
+
+
+
+
+

网络拓扑说明

+

部署数瑞智能合约引擎最小仅需一个节点,此时可用作调试、测试,不能通过多节点模式来实现可信的计算。 +单节点部署时,可通过配置账本实现”防抵赖”的计算,但不能实现”难篡改”的计算。

+

多节点部署时可参考下图,包含三种逻辑节点,同一虚拟机可安装一至三种节点。

+

1)账本节点。即数瑞图式账本。

+

2)合约节点。运行代码逻辑,并通过内存缓存实现高响应的模块。与其他合约节点组成可信计算网络。

+

3)路由节点。各个合约节点的路由信息。一般单个路由节点可支持最高1000合约节点。可视情况部署多个路由节点,并在路由节点之间配置实现更大规模的节点组网。

+

一般地,同一虚拟机下,会部署合约节点与账本节点

+

deploytopology

+
+
+
+

智能合约节点安装

+

打开安装包下载链接 +其中,下载bdserver-lite.zipbdserver.zip,其中,bdserver.zip包含更多示例和文档。 +下载之后解压并启动。

+
unzip -d ./bdserver bdserver-lite.zip
+cd bdserver
+chmod +x *.sh
+sh cmstart.sh
+
+
+
+
+
+

路由准入节点安装

+

打开安装包下载链接 +其中,下载bdserver-cluster.zip。 +下载之后解压并启动。

+
unzip -d ./bdcluster bdserver-cluster.zip
+cd bdcluster
+chmod +x *.sh
+sh ncstart.sh
+
+
+
+
+
+

文件说明

+
+

智能合约节点

+

bdserver目录

+

该目录下的文件说明:

+

1.cmstart.sh 该脚本用于启动合约引擎。合约引擎默认监听8080端口,可通过修改cmstart.sh来修改合约引擎的监听端口。

+

2.BDWareProjectDir 该目录存放了本节点的所有合约项目。

+

3.WebContent 该目录存放了本节点的前端代码。

+

4.cp, 该目录存放了yjs.jar,为启动合约实例所需的jar。

+

5.bdserver.jar 对外提供http/websocket的服务器逻辑。

+

6.updateContract.sh 用于升级的脚本。

+
+
+

路由准入节点

+

安装脚本会自动下载安装并解压为bdcluster目录。 +该目录下的文件说明:

+

1.ncstart.sh 该脚本用于启动节点准入中心。默认监听1718端口。可通过修改ncstart.sh来修改监听的端口。

+

2.WebContent 该目录存放了准入中心的前端代码。

+

3.bdcluster.jar 准入中心的后端。

+
+
+
+
+

升级流程

+
+

合约节点

+

在命令行中输入:

+
sh updateContract.sh
+
+
+

亦可通过public.internetapi.cn,下载最新文件,单独升级yjs.zip/bdserver-jar.zip/AgentWebContent来升级。

+
+
+

路由准入节点

+
sh updateCluster.sh
+
+
+

亦可通过public.internetapi.cn,下载最新文件,单独升级bdserver-cluster.zip/ClusterWebContent.zip来升级。

+
+
+
+
+

使用说明

+
+

通过参考界面使用

+

当保留了WebContent目录的情况下,可使用浏览器进行配置。 +更多请使用见左侧文档BDContract参考界面使用说明

+
+

BDWare OnlineIDE

+

打开BDWare OnlineIDE

+
+
+

BDWare NodePortal

+

打开BDWare NodePortal

+

如需组网,使用跨节点功能,则需安装路由准入中心。并按以下步骤进行配置。涉及两组公私钥。 +第一组公私钥为合约节点的、有NodeManager权限的公私钥。 +第二组公私钥为路由准入节点的、有CenterManager权限的公私钥。

+

1.打开NodePortal.html,复制该节点的NodeManager公私钥。

+

2.打开CenterPortal.html,点击右上角,将上述的NodeManager公私钥导入;并选择”NodeManager”进行身份认证。

+

3.在CenterPortal.html中切换CenterManager的公私钥,点左侧的”用户管理”,通过NodeManager的认证请求。

+

4.使用NodeManager权限的公私钥打开NodePortal.html,点击:“节点管理”菜单,并配置加入网络。 +其中,加入网络的格式为:ws://centerportal的ip:端口+1。 +配置示例

+
+
+
+

通过SDK使用

+
+

基础知识

+

Websocket

+

Sm2加密的使用

+
+
+

SDK下载

+
    +
  1. Java版本的客户端下载:BDWareJavaClient。具体使用说明请下载后解压,查看README.md,并参考ContractAPI

  2. +
+

2.Javascript版本的客户端下载:BDWareWebClient。具体使用说明请下载后解压,查看README.md,并参考ContractAPI

+

3.配置工具BDWareConfigTool。具体说明请下载后解压,使用以下命令查看帮助:

+
java -jar java-client.jar -h
+
+
+
+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/Introduction.html b/doc/markdown_BDWare/Introduction.html new file mode 100644 index 0000000..b54b00d --- /dev/null +++ b/doc/markdown_BDWare/Introduction.html @@ -0,0 +1,329 @@ + + + + + + + + + + 北大数瑞介绍 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

北大数瑞介绍

+
+
+

什么是北大数瑞?

+

北大数瑞是面向大数据场景的数据资源、IoT资源、云资源的管理、调度平台。BDContract是一个可信计算框架,计算逻辑以智能合约的方式表达。通过”随机“和”冗余计算“的方式实现智能合约的可信执行。BDContract在保证智能合约的可用性、可靠性的同时,着重提升执行效率和安全性。

+
+
+
+

特点

+
    +
  1. 支持多种执行模式,权衡可用性、可靠性、正确性和效率。

  2. +
  3. 接入各种数据源。

  4. +
  5. 支持合约的细粒度监测。

  6. +
  7. 支持合约的状态。

  8. +
  9. 访问控制。

  10. +
  11. 支撑跨语言调用。

  12. +
+
+
+
+

使用开源项目说明

+

BDWare项目站在了许多巨人的肩膀上,感谢这些开源项目。

+

本项目的智能合约后端使用了以下开源库。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称Licence类型说明
Project NashornGPLv2使用了该项目的编译器,可以将js函数编译为java字节码
ASM OW2BSD with attribution基于asm的TreeAPI与VisitorAPI实现合约的静态分析框架
NettyApache License 2.0使用netty作为Http/Websocket的服务端
gRPCApache License 2.0使用gRPC与BDWareLedger通讯
RocksDBGPLv2后台数据库
ANTLRBSD对合约脚本的词法分析与语法分析
SM2Java国密SM2 Java语言实现

本项目的智能合约前端使用了以下开源库。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称Licence类型说明
BootstrapMIT前端的排版、样式
jQueryMIT用于操作DOM的javascript库
jQueryUIMIT前端UI构件库
DataTablesMIT表格样式
CodeMirrorMIT代码编辑框样式
eChartsApacheV2统计图表
sm-cryptoMIT国密SM2 javascript语言实现

本项目的文档使用Sphinx生成,感谢readthedocs提供文档样式。

+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/YJSAPI.html b/doc/markdown_BDWare/YJSAPI.html new file mode 100644 index 0000000..e69a6e5 --- /dev/null +++ b/doc/markdown_BDWare/YJSAPI.html @@ -0,0 +1,1848 @@ + + + + + + + + + + YJS SDK — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

YJS SDK

+
+

YJS Build-in API

+
+

内置对象 Global

+
+
+

内置对象 requester

+

该内置对象在export function里面会有值,仅当合约调用签名验证通过。

+
+
+

执行合约 executeContract

+

参数:

+
action:executeContract; 
+contractID:合约的id或名称均可;
+operation:调用合约的方法名;
+arg: 参数;格式为JSON字符串,有action与arg两个字段。
+
+
+

可选参数:

+
requestID:字符串类型,自行生成,用于查询hash
+
+
+

使用示例:

+
 function testExecutorContract(arg){
+    var ret = JSON.parse(executeContract("ElemeProvider","queryDB",arg));
+    if (ret.status == "Success"){
+      return JSON.parse(ret.result);
+    }else return null;
+  }
+
+
+
+
+

订阅事件主题 subscribe

+

参数

+
contractID:字符串类型 合约id或名称均可。
+event:字符串类型
+handler:方法名,该方法必须接受Event(内含字段topic和content)类型的唯一变量为参数;可以不是export方法
+
+
+

使用示例:

+
export function init(arg) {
+    YancloudUtil.subscribe("topic", handler);
+    print("Handler: " + handler);
+}
+
+function handler(e) {
+    print("topic: " + e.topic);
+    print("content: " + e.content);
+}
+
+
+
+
+
+

发布事件 pubEvent

+

参数

+
topic:字符串类型,发布的事件主题
+content:字符串类型,发布的事件内容
+
+
+

使用示例:

+
export function pub1(arg) {
+    YancloudUtil.pubEvent("topic", arg);
+    return "done";
+}
+
+
+

也可以在合约开头定义事件,则事件名即为事件主题,此时可直接使用事件作为方法名发布事件

+
event topic;
+export function pub2(arg) {
+    topic(arg);
+    return "done";
+}
+
+
+

该写法与上面的pub1等价。

+
+

访问资源文件

+

通过Global.Resources去加载ypk内部的资源文件。

+
+

loadAsInputStream

+

参数:

+
path:字符串类型 需要加载文件的地址
+
+
+

使用示例:

+
var file = Global.Resources.loadAsInputStream("/deleteit.txt");
+
+
+
+
+

loadAsScanner

+

参数:

+
path:字符串类型 需要加载文件的地址
+
+
+

使用示例:

+
var scanner = Global.Resources.loadAsScanner("/local.txt");
+
+
+
+
+
+
+

YJS Build-in Annotation

+
+

@Access

+

设置合约的调用是否需要签名,这里分为两种,需签名和无签名。 +其中,”verified”表示需要签名。其他则表示无需签名。

+
@Access("verified")
+export function easy(arg){
+    return "true";
+}
+
+
+
+
+

@LogType

+

LogType注解通过参数的方式声明合约或函数的需要记录的日志类型。

+

其中,Arg表示日志中记录合约执行的参数;Result表示记录合约执行的返回结果;Branch表示记录合约执行分支。

+

例如 ,通过如下LogType注解来声明函数

+
@LogType("Arg","Result","Branch")
+export function easy(arg){
+    Global.a = "a";
+    Global.b = "b";
+    if(arg > 0)
+        return Global.a;
+    else
+        return Global.b;
+}
+
+
+
+
+

@LogLocation

+

该注解可以修饰contractfunction。 +设置日志存储的位置。参数中指定为“dataware”则存储在账本和本地,如果没有指定为“dataware”则仅存储在本地。 +例如,通过如下LogLocation设置存储位置。

+

在BaaS平台中,可以指定账本名称,BaaS平台默认账本为default,使用 +@LogLocation("bdledger:default")。如想保存到自定义的账本,比如,”abc”账本,就使用 +@LogLocation("bdledger:abc")

+
@LogLocation("dataware")
+export function easy(arg){
+    Global.a = "a";
+}
+
+
+
+
+

@Permission

+

该注解只能修饰contract +设置合约中调用的工具类的权限,包括File、Http、MySQL、MongoDB、RocksDB等工具类。如果合约中用到了以上工具类,需要在注解中添加对应的授权字段,默认只有YJS自带的YancloudUtil;如果没有添加则会抛出”未授权工具类”的异常。 +这6种工具类的详细说明在本小节后续中有说明。

+
@Permission("Http","File")
+contract HttpPermission {
+    export function main(args){
+        var http=HttpUtil.httpGet(args);
+        var dir="adf/adfas/";
+        var file=FileUtil.getDir(dir);
+        return YancloudUtil.currentTimeMillis();
+    }
+}
+
+
+
+
+

@Description

+

该注解可以修饰contractfunction。 +传入合约及函数的简介,可用于生成说明文档中关于exported函数的介绍。

+
@Description("返回数据条目,无需参数")
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+

@Param

+

该注解可以修饰function。 +提供调用函数的参数示例,也为生成说明文档中的返回结果提供默认参数。

+
@Param({"offset":0,"count":100})
+export function get(args){
+    var offset = args.offset;
+    var count = args.count;
+    ...
+}
+
+
+
+
+

@MockTemplate

+

该注解可以修饰function。 +提供函数的返回模拟数据模板,用于描述返回值的格式.若加此注解在debug方式调用时,返回按照此格式生成的模拟数据。

+

####支持的字段类型

+
@integer
+@string
+@boolean
+@date
+@time
+@datatime
+/[a-z][A-Z][0-9]/    (正则表达式)
+……
+详细格式可以参考http://mockjs.com/examples.html
+
+
+

####注意:模板的格式为{‘result’:模板}

+
//返回一个1-100之间的整数
+@MockTemplate({'result|1-100':1})
+//返回
+{'result':76}
+
+//返回一个1-5个数的数组
+@MockTemplate({'result|1-5':[{'value|1-100':1}]})
+//返回
+{"result":[{"value":34},{"value":8},{"value":48},{"value":50},{"value":43}]}
+
+//返回一个对象包含如下字段
+@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
+//返回
+{"password":"3ZLc","name":"William Young","id":36097783842688,"email":"d.fuunwe@gqnr.to"}
+
+//返回元素个数为1-5个之间的一个数组,数组的每个元素都是上述格式的一个对象
+{'result|1-5':[{'id':'@integer','email':'@email','password':'@string','name':'@name'}]}
+//返回
+[
+  {"password":"dO]wW","name":"Jeffrey Lopez","id":1783453207480410,"email":"a.ckokgxrga@hgiesugi.bb"},
+  {"password":"BQYRL","name":"Brian Moore","id":4310212972071102,"email":"k.lbpxocydrh@msgnjtox.na"},
+  {"password":"Gw1","name":"Susan Jackson","id":7766580783668916,"email":"h.zjgusl@htce.cr"}
+]
+
+
+
@MockTemplate({'result':{'id':'@integer','email':'@email','password':'@string','name':'@name'}})
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+

@Result

+

该注解可以修饰function。 +若没有模拟数据模板,则返回模拟数据时使用该注解的内容 +提供函数的返回结果示例,若加此注解则生成说明文档时将直接返回此结果而不使用默认参数调用函数。

+
@Result(666)
+export function count(args){
+    var  sql = "select count(*) from data;";
+    var conn = getConn();
+    var statement = conn.createStatement();
+    var resultSet = statement.executeQuery(sql);
+    var c = {};
+    resultSet.next();
+    c.count = resultSet.getLong(1);
+    return JSON.stringify(c);
+}
+
+
+
+
+
+

IO工具类

+
+

概览

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IO工具类名称说明
FileUtil文件操作相关的类
LedgerUtil账本操作相关的类
HttpUtilHttp接口相关的类
DOIPUtilDoIP相关的类
MySQLUtil连接mysql数据库
MongoDBUtilMongoDB连接相关的类
RocksDBUtilRocksDB(基于本地文件的k-v数据库)
BDWareTimeSeriesDBUtil基于本地文件的时间序列数据库
+
+

FileUtil

+

可以使用@Permission(“File”)来引入FileUtil对象。

+
@Permission("File")
+contract FileSample {
+...
+}
+
+
+

该对象支持以下方法:

+
+

copyTo

+

可以复制文件和目录。第一个参数是source,第二个参数是destination。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1src类型为String
2dest类型为String
+
+
使用示例
+
var ret = FileUtil.copyTo("./source.txt","./dest.txt");
+
+
+
+
+
+

getContent

+

获取文件的文本内容,当文件不存在时,返回undefined

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1path类型为String
+
+
使用示例
+
var ret = FileUtil.getContent("./source.txt");
+
+
+
+
+
+

getDir

+

获取文件所在的文件夹名,输入参数为字符串。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1path类型为String
+
+
使用示例
+
var ret = FileUtil.getDir("./parent/src.txt");
+// ret 为 "./parent/";
+
+
+
+
+
+

getFileName

+

获取文件名。输入参数为字符串。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1path类型为String
+
+
使用示例
+
var ret = FileUtil.getFileName("./parent/src.txt");
+// ret 为 "src.txt"
+
+
+
+
+
+

openFileAsPrinter

+

以PrintStream的形式打开文件。 +返回结果是java.io.PrintStream类型。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1path文件名,类型为String
2isAppend类型为boolean,表示是否往文件末尾添加
+
+
使用示例
+
var ret = FileUtil.openFileAsPrinter("./parent/src.txt",true);
+ret.println("hello");
+ret.close();
+
+
+
+
+
+
+

LedgerUtil

+

可以使用@Permission(“Ledger”)来引入LedgerUtil对象。

+
@Permission("Ledger")
+contract LedgerExample{
+...
+}
+
+
+
+

getClient

+

获取一个连接客户端,一个参数,为对象类型。 +返回结果为LedgerClient类型,用于后续的查询账本等操作。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1address包含ip和端口两个字段
+
+
使用示例
+
var address = {};
+address.ip = "127.0.0.1";
+address.port = 18091;
+var ledgerClient = LedgerUtil.getClient(address);
+
+
+
+
+
+

queryByHash

+

根据Hash查询Transaction。 +返回结果为对象,包含from、to、type和data四个字段,均为String类型。 +其中data为按utf-8编码解析字节数组,如果存证时用的不是utf8编码,可能返回乱码。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1client通过getClient方法获得的对象
2info对象类型,有两个字段ledger和hash,均为字符串类型
+
+
使用示例
+
// ... ledgerClient = LedgerUtil.getClient(...);
+var info = {};
+info.ledger = "bdcontract";
+info.hash = "4d3b75750835092a50085127702669615b602e53";
+var ret = LedgerUtil.queryByHash(ledgerClient,info);
+print(ret.from);
+print(ret.to);
+print(ret.type);
+print(ret.data);
+
+
+
+
+
+

sendTransaction

+

存证数据。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1client通过getClient方法获得的对象
2info对象类型,有from\to\data三个字段,均为String类型
+
+
使用示例
+
// ... ledgerClient = LedgerUtil.getClient(...);
+var info = {};
+info.ledger = "bdcontract";
+info.from = "b60e8dd61c5d32be8058bb8eb970870f07233155";
+info.to = "b60e8dd61c5d32be8058bb8eb970870f07233155";
+info.data = "hello world";
+var ret = LedgerUtil.sendTransaction(ledgerClient,info);
+//ret为存证的哈希值
+print(ret);
+
+
+
+
+
+
+

HttpUtil

+

可以使用@Permission(“Http”)来引入HttpUtil对象。

+
@Permission("Http")
+contract HttpExample{
+...
+}
+
+
+
+

createAPIGate

+

配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1ip字符串类型,ip,端口默认为6161
+
+
使用示例
+
var ret = HttpUtil.createAPIGate("192.168.4.4");
+ret.get("com.tencent.mm","sendMsg","msg");
+print(ret);
+
+
+
+
+
+

createAPIGate

+

配合手机的元邦使用,当手机安装元邦且安装了API 接口后,可成为数据来源。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1ip字符串类型,ip
2port字符串类型,端口
+
+
使用示例
+
var ret = HttpUtil.createAPIGate("192.168.4.4", "6161");
+ret.get("com.tencent.mm","sendMsg","msg");
+print(ret);
+
+
+
+
+
+

get

+

发起Http的get请求。 +返回结果为对象类型,包含response和responseCode两个字段。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1url字符串,表示url类型
+
+
使用示例
+
var ret = HttpUtil.get("https://www.baidu.com");
+print(ret.responseCode);
+print(ret.response);
+
+
+
+
+
+

post

+

发起Http的post请求。 +返回结果为对象类型,包含response和responseCode两个字段。

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1args对象类型,有url,headers和data三个字段。其中,args.headers为对象类型。
+
+
使用示例
+
var req = {};
+req.url = "https://www.baidu.com";
+req.data = "hello";
+req.header = {};
+req.header.Accept = "application/json";
+req.header["Content-Type"] = "application/json";
+var ret = HttpUtil.post(req);
+print(ret.resposeCode);
+print(ret.response);
+
+
+
+
+
+
+

DOIPUtil

+

可以使用@Permission(“DOIP”)来引入DOIPUtil对象。

+
@Permission("DOIP")
+contract DOIPExample{
+  ...
+}
+
+
+
+

call

+

调用一个DO

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型, 目标DO标识
2arg1字符串类型, 输入参数字符串
+
+
使用示例
+
var ret = DOIPUtil.call("86.5000.470/do.hello","inputString");
+
+
+
+
+
+

create

+

向一个Repository创建一个字符串类型DO

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型, 目标Repo标识
2arg1对象类型,包括doID,doBody字段
+
+
使用示例
+
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
+var ret = DOIPUtil.create("86.5000.470/repo.localTcpRepo",digitalObject);
+
+
+
+
+
+

delete

+

从一个Repository中删除DO

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
2arg1字符串类型 目标Repo标识
+
+
使用示例
+
var ret = DOIPUtil.delete("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo");
+
+
+
+
+
+

hello

+

获取目标Repository的DOIP服务信息

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标Repo标识
+
+
使用示例
+
var ret = DOIPUtil.hello("86.5000.470/repo.localTcpRepo");
+
+
+
+
+
+

listOperation

+

获取目标DO支持的DOIP操作

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
+
+
使用示例
+
var ret = DOIPUtil.listOperation("86.5000.470/do.hello");
+
+
+
+
+
+

register

+

向LHS注册一个DO,返回分配的标识

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 DO所在Repo标识
2arg1字符串类型 DO格式描述字符串
+
+
使用示例
+
var ret = DOIPUtil.register("86.5000.470/repo.localTcpRepo","String");
+
+
+
+
+
+

reregister

+

修改LHS中DO的注册信息

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
2arg1字符串类型 DO所在Repo标识
3arg2字符串类型 DO格式描述字符串
+
+
使用示例
+
var ret = DOIPUtil.reregister("86.5000.470/do.hello","86.5000.470/repo.localTcpRepo","String");
+
+
+
+
+
+

retrieve

+

获取一个DO

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 目标DO标识
+
+
使用示例
+
var ret = DOIPUtil.retrieve("86.5000.470/do.hello");
+
+
+
+
+
+
+

test

+

测试DOIPUtils是否可用

+
+

参数

+ + + + + + + + + + + + + + + +
序号参数说明
1arg0字符串类型 任意字符串
+
+

使用示例

+
var ret = DOIPUtil.test("hello");
+
+
+
+
+

update

+

更新目标DO

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0JS对象,包括doID,doBody字段
+
+
使用示例
+
var digitalObject = JSON.parse("{\"doID\":\"86.5000.470/do.hello\",\"doBody\":\"hello world\"}");
+var ret = DOIPUtil.update(digitalObject);
+
+
+
+
+
+
+

MySQLUtil

+

可以使用@Permission(“MySQL”)来引入MySQLUtil对象。

+
@Permission("MySQL")
+contract MySQLExample{
+...
+}
+
+
+
+

getConnection

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1URL字符串类型,jdbc连接
2usrName字符串类型,用户名
3pwd字符串类型,密码
+
+
使用示例
+
var url = "jdbc:mysql://xx.xx.xx:port/tableName";
+var usrName = "xxx";
+var pwd = "xxx";
+//配置好用户名和密码,url格式为ip或域名+端口,中间以”:”隔开。
+var conn = MySQLUtil.getConnection(url,usrName,pwd);
+//获取数据库连接
+var sql = "select * from newele.data";
+//创建查询语句
+var statement = conn.createStatement();
+var resultSet = statement.executeQuery(sql);
+var waimailist  = [];
+//解析查询结果
+var meta = resultSet.getMetaData();
+for (;resultSet.next();){
+  var line = {};
+  for (var j=1;j<=meta.getColumnCount();j++){
+    line[meta.getColumnName(j)] = resultSet.getString(j);
+  }
+	waimailist.push(line);
+}
+
+
+

其中,getConnection方法返回的对象通过反射机制绑定到了Java的一个java.util.Connection对象。因此,可以查看: +https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html +以了解如何进行Mysql数据库操作。

+
+
+
+
+

MongoDBUtil

+

可以使用@Permission(“MongoDB”)来引入MongoDBUtil对象。

+
@Permission("MongoDB")
+contract MongoDBExample{
+...
+}
+
+
+
+

getConnection

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1URL字符串类型 数据库的URL
2port整数类型 端口号
3dbName字符串类型 数据库的名称
4usrName字符串类型 数据库的用户名
5pwd字符串类型 数据库的密码
+
+
使用示例
+

注意:port为整型,其他参数为String类型

+
var client = MongoDBUtil.getConnection(url,port,dbName,usrName,pwd);
+//获取数据库对象
+var db = client.getDatabase("yancloud");
+var collection = db.getCollection("containers");
+var iter = collection.find().iterator();
+var ret ="";
+for (;iter.hasNext();){
+	ret+=iter.next().toJson();
+	ret+="\n";
+}
+
+
+

其中,getMongoDBClient对象通过反射机制绑定到了Java的一个com.mongodb.MongoClient对象。因此,可以查看: +https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClient.html

+

以了解该对象的更多方法和使用方式。

+
+
+
+
+

RocksDBUtil

+

使用@Permission(“RocksDB”)来引入RocksDBUtil对象。

+
@Permission("RocksDB")
+contract RocksDBSample {
+...
+}
+
+
+
+

loadDB

+

通过loadDB来加载一个RocksDB数据库。 +加载后,可进行get/delete/put等操作。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1path字符串类型 数据库部署的路径
2readOnly布尔类型 数据库只读
+
+
使用示例
+
@Permission("RocksDB")
+@Description("这是个使用RocksDB的参考代码")
+contract RocksDBSample{
+  function onCreate(){
+    Global.rocksdb = RocksDBUtil.loadDB("./dbdir/","false");
+  }
+  @Description("示例参数: {\"key\":\"abc\",\"value\":\"def\"}")
+  export function put(arg){
+    arg = JSON.parse(arg);
+    Global.rocksdb.put(arg.key,arg.value);
+    return "success";
+  }
+  @Description("示例参数: \"abc\"}")
+  export function get(arg){
+    return Global.rocksdb.get(arg);
+    return "failed";
+  }
+  @Description("示例参数: \"abc\"")
+  export function deleteKey(arg){
+    return Global.rocksdb.delete(arg);
+  }
+  @Description("遍历KV库,无需参数")
+  export function iter(arg){
+    var iter = Global.rocksdb.newIterator();
+    var obj = undefined;
+    var ret = {
+    };
+    for (iter.seekToFirst();(obj=Global.rocksdb.getNext(iter))!=undefined;){
+      ret[obj.key]=obj.value;
+    }
+    return JSON.stringify(ret)
+  }
+}
+
+
+
+
+
+
+

BDWareTimeSeriesDBUtil

+

使用示例

+
@Permission("BDWareTimeSeriesDB")
+contract BDWareTimeDBExample{
+  function onCreate(arg){
+    Global.dbutil = BDWareTimeSeriesDBUtil.getConnection();
+  }
+
+  export function put(arg){
+    //第一个参数为表名,第二个参数为要放的value,时间戳自动打。
+    Global.dbutil.put("defaultTable",arg);
+    return "success";
+  }
+  @Param
+  export function getCount(arg){
+    return Global.dbutil.getCount("defaultTable");
+  }
+  @Param(1617254937373)
+  export function queryByStartTime(arg){
+    var startDate = java.lang.Long.valueOf(arg);
+    //查询从开始时刻startDate到最新的数据
+    var list = Global.dbutil.query("defaultTable",startDate);
+    var ret=[];
+    print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
+    var i=0;
+    for (i=0;i<list.size();i++){
+      print(i+"-->"+list.get(i));
+      ret.push(list.get(i));
+    }
+    return ret;
+  }
+  
+  @Description("示例参数: {\"offset\":1,\"len\":1}")
+  @Param({"offset":1,"len":1})
+  export function queryByOffset(arg){
+    var offsetLen = JSON.parse(arg);
+    //可配合getCount使用,查询第offset至offset+len条数据
+    var list = Global.dbutil.queryByOffset("defaultTable",offsetLen.offset,offsetLen.len);
+    var ret=[];
+    print("DBUtil"+Global.dbutil+" list:"+list+" list.size"+list.size());
+    var i=0;
+    for (i=0;i<list.size();i++){
+      print(i+"-->"+list.get(i));
+      ret.push(list.get(i));
+    }
+    return ret;
+  }
+}
+
+
+
+
+
+

加解密工具类

+
+

SM2

+

可以使用@Permission(“SM2”)来引入SM2Util对象。

+
@Permission("SM2")
+contract SM2Sample {
+...
+}
+
+
+
+

generateKeyPair

+

生成公私钥。

+
+
参数
+

无参数。

+
+
+
使用示例
+
var ret = SM2Util.generateKeyPair();
+print(ret.publicKey);
+print(ret.privateKey);
+return JSON.stringify(ret);
+
+
+
+
+
+

sign

+

签名。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1content字符串类型 要进行签名的内容
2keyPairsm2
+
+
使用示例
+
var keypair = SM2Util.generateKeyPair();
+var ret = SM2Util.sign("Hello",keypair);
+print(ret.status);
+//如果status是success
+print(ret.signature);
+//如果status是failed
+print(ret.message);
+
+
+
+
+
+

verify

+

验签。

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1content字符串类型 待验签的内容
2signature字符串类型 签名
3publicKey字符串类型 公钥
+
+
使用示例
+
var ret = SM2Util.verify("Hello","....签名","...公钥");
+// 验证通过时,result为true,status为success
+// 失败时,result为failed,status为failed
+print(ret.status);
+print(ret.result);
+
+
+
+
+
+
+
+

多线程工具类

+
+

AsyncUtil

+

可以使用@Permission(“Async”)来引入AsyncUtil对象。

+
@Permission("Async")
+contract AsyncExample{
+  export function longTimeTask(arg){
+    var a = {
+    };
+    a.count = 100;
+    AsyncUtil.postFunction(taskFun,a);
+  }
+  function taskFun(arg){
+    Global.progress = 0;
+    for (var i=0;i<arg.count;i++){
+      AsyncUtil.sleep(100);
+      Global.progress++;
+    }
+  }
+  export function getProgress(arg){
+    return Global.progress;
+  }
+}
+
+
+
+

postFunction

+
+
参数
+ + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0ScriptFunction
2arg1对象
+
+
使用示例
+
var ret = AsyncUtil.postFunction(a,{"a":"b"});
+
+
+
+
+
+

setInterval

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0ScriptFunction
2arg1long
3arg2long
4arg3对象
+
+
使用示例
+
var ret = AsyncUtil.setInterval(a,100,1000,"abc");
+
+
+
+
+
+

setTimeOut

+
+
参数
+ + + + + + + + + + + + + + + + + + + + + + + + + +
序号参数说明
1arg0ScriptFunction
2arg1long
3arg2Object
+
+
使用示例
+
var ret = AsyncUtil.setTimeOut(a,100,"abc");
+
+
+
+
+
+

sleep

+
+
参数
+ + + + + + + + + + + + + + + +
序号参数说明
1arg0long
+
+
使用示例
+
var ret = AsyncUtil.sleep();
+
+
+
+
+
+
+ +
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/YJSInDepth.html b/doc/markdown_BDWare/YJSInDepth.html new file mode 100644 index 0000000..2434fc9 --- /dev/null +++ b/doc/markdown_BDWare/YJSInDepth.html @@ -0,0 +1,457 @@ + + + + + + + + + + YJS语法 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
+

YJS语法

+
+
+

概述

+

YJS源文件包括任意数量的import声明和一个contract定义

+
+
+
+

import声明

+

与JavaScript(ES6)类似,YJS也支持import声明语句,在全局层面,开发者可以使用如下import声明来导入其他文件。

+
import "filename";
+
+
+
+

内容

+

import声明语句将包含在“filename”文件中的所有全局符号(单元)导入到当前文件,且全局范围内有效。

+
+
+

路径

+

filename通常用**/做目录分隔符来表示文件的路径,例如,从同一目录下导入x.yjs文件到当前文件,可以使用import “x.yjs”语句;从其他目录下导入x.yjs使用import “lib/x.yjs”**语句。

+
+
+
+
+

Contract定义

+
+

示例

+

以下是一个合约示例,用于JSON处理,此YJS源文件以合约名称命名。

+
contract ScoreAdder{
+	//arg =  {"action":"main","arg":"[{\"score\":20},{\"score\":20}]"}
+	export function main(arg){
+		//JSON is a build-in object.
+		var point = JSON.parse(arg);
+		var s = 0;
+		print(point[0].score);
+		print(point.length);
+		for (var i=0;i<point.length;i++){
+			s+=point[i].score/1.0;
+		}
+		print("total score= "+s);
+		return s;
+	}
+}
+
+
+
+
+

注释

+

YJS源文件支持以(//)表示的单行注释和以(/*…*/)表示的多行注释,如下所示:

+
// 这是一个单行注释
+/*
+ * 这是一个
+ * 多行注释
+ */
+
+
+
+
+

注解

+

与Java类似,YJS也支持注解声明合约和函数。

+

在YJS中,有几种内建注解:LogType、LogLocation、Access、Permission。 +当然,可以自定义注解。 +内建注解的详细使用方式可以通过YJS内置API文档查看。 +开发者可以使用如下注解来声明合约和函数。

+
@LogType("Arg","Result","Branch")
+@SelfDefinedAnntation("dad",1)
+@Access
+function xxx(){}
+
+
+
+
+

结构

+

YJS中的合约类似于Java中的类。每个合约都定义了一定数量的变量函数事件

+
+

变量

+

YJS中的变量类似于JavaScript(ES6)中的变量,分为全局变量局部变量

+

全局变量:

+
judge =  true;
+
+
+

局部变量:

+
var vs = "This is a string";
+
+
+

所有的变量都是动态类型,因为变量的具体类型是根据变量值来决定的。如上示例中,全局变量judge是bool类型,局部变量vs是字符串类型。

+
+
+

函数

+

函数是合约中的可执行单元。YJS中有两种类型的函数:普通函数和用export关键字修饰的exported函数。

+

以下是exported函数和普通函数的区别:

+
    +
  1. 只有exported函数能被其他合约调用。

  2. +
  3. exported函数只能有一个参数且参数类型必须为String。

  4. +
  5. exported函数的返回类型必须是String。

  6. +
  7. 内置对象requester(请求者的公钥)只能存在于exported函数或onCreate函数,因为onCreate()虽然没被export关键字修饰,但它自带requester对象且该函数可以自动执行。

  8. +
+
+
+

事件

+

YJS中的事件类似于Solidity中的事件。

+

发布者定义一个包含事件发布函数的事件,然后通过调用事件发布函数发布事件。

+

订阅者订阅并处理事件。

+

事件示例如下:

+

EventPuber.yjs

+
contract EventPuber{
+	event abcEvent;
+  	export function pub(arg){
+		abcEvent(arg);
+  		return "done!";
+	}
+}
+
+
+

EventSuber.yjs

+
contract EventSuber{
+  	export function init(arg){
+		YancloudUtil.subscribe("EventPuber","abcEvent",handler);
+        print("Handler:"+handler);
+	}
+  	function handler(e){
+        var ret = "ReceiveEvent:"+(e.type)+" "+(e.content);
+		print(ret);
+	}
+}
+
+
+
+
+
+
+
+

YJS项目

+

除了只包含一个contract定义的YJS源文件,YJS引擎还支持YJS项目

+

每个YJS project包含了合约执行过程中需用到的各种文件,包括yjs源文件**”.yjs”和其他资源文件,如”mainfest.json”, “.js”, “.txt”,”.jar”**, …

+
+

Manifest.json

+

每个YJS项目在项目的根目录下必须有一个mainfest.json文件,此文件描述了合约对于YJS的编译工具(YJS引擎)所需的必要信息。

+
+

Manifest结构

+

manifest文件需包含以下信息:

+
    +
  1. main: 项目中将要被执行的合约文件。

  2. +
  3. type: 合约的类型,如数据合约/算法合约…

  4. +
  5. builder: 构建YJS项目的开发者姓名。

  6. +
  7. insnLimit: 运行合约需要消耗的值。

  8. +
  9. pyDependences: 项目所需的Python依赖。

  10. +
+
+
+

Manifest示例

+
{
+	"main": "contract.js",
+	"type": "Data",
+	"builder": "caihq",
+	"permissions": 0L,
+	"pyDependences": [
+        {
+            "name": "yjsexample",
+            "modules": [
+                {
+                    "name": "sample"
+                }
+            ]
+        }
+    ]
+}
+
+
+
+
+
+

YJS-Java

+

Jar文件实现了YJS与其他编程语言间的跨语言调用,如YJS-Java, YJS-Python, … 通过将Java文件包成jar包的方式,使得合约可直接调用Java中的方法。

+

Java class:

+
package your.own.pkg;
+public class HelloWorld {
+ public static int fun(String arg){
+  return arg.length;
+ }
+ public int fun2(String arg){
+  return arg.length;
+ }
+}
+
+
+

InvokeJava.yjs

+
contract InvokeJava{
+ export function main(arg){
+  var Hello = Java.type("your.own.package.HelloWorld");
+  var hello = new Hello();
+  return Hello.fun(arg)+hello.fun2(arg);
+ }
+}
+
+
+
+
+

YJS-前端

+

使用数瑞客户端来访问智能合约支持从智能合约中获取html/js/css等资源文件, +并在BDWareWebClient中渲染。 +首先在合约中import以下模块。

+
module Viewable{
+  export function loadResource(arg){
+    return Global.Resources.loadAsString(arg);
+  }
+  export function needRender(arg){
+    return true;
+  }
+}
+
+
+

同时,import以后,定义一个getMainFrame方法,以便数瑞客户端识别主页:

+
export function getMainFrame(arg){
+  return "/html/main.html";
+}
+
+
+

该方法的返回结果为一个资源文件的路径。 +示例的资源文件”/html/main.html”如下:

+
<div>
+<button onclick="queryDataFromContract()">Hello,</button> Data from contract:
+<span id="resultText"></span>
+<script fromContract="/html/hello.js"></script>
+<link fromContract="/html/hello.css"/>
+</div>
+
+
+

示例的资源文件”/html/hello.js”如下:

+
var queryDataFromContract = function(){
+    //第一个参数为函数名,第二个为参数,第三个参数为回调。
+	var data = executeCurrentContract("query","abc",function(argg){
+    	$("#resultText")[0].innerHTML = argg.result;
+    });
+}
+
+
+

参考示例:

+
+
+

YJS-Python

+

TODO

+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/markdown_BDWare/httpapi.html b/doc/markdown_BDWare/httpapi.html new file mode 100644 index 0000000..259ebe9 --- /dev/null +++ b/doc/markdown_BDWare/httpapi.html @@ -0,0 +1,738 @@ + + + + + + + + + + Request Examples {#_request_examples} — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +
type: google.api.Service
+config_version: 3
+
+http:
+  rules:
+    - selector: bdware.bdledger.api.Node.ClientVersion
+      get: /v0/node/version
+    - selector: bdware.bdledger.api.Ledger.CreateLedger
+      post: /v0/ledgers
+      body: "*"
+    - selector: bdware.bdledger.api.Ledger.GetLedgers
+      get: /v0/ledgers
+    - selector: bdware.bdledger.api.Ledger.SendTransaction
+      post: /v0/ledgers/{ledger}/transactions
+      body: "*"
+    - selector: bdware.bdledger.api.Query.GetBlockByHash
+      get: /v0/ledgers/{ledger}/block
+    - selector: bdware.bdledger.api.Query.GetBlocks
+      post: /v0/ledgers/{ledger}/blocks/query
+      body: "*"
+    - selector: bdware.bdledger.api.Query.CountBlocks
+      post: /v0/ledgers/{ledger}/blocks/count
+      body: "*"
+    - selector: bdware.bdledger.api.Query.GetRecentBlocks
+      get: /v0/ledgers/{ledger}/blocks/recent
+    - selector: bdware.bdledger.api.Query.GetTransactionByHash
+      get: /v0/ledgers/{ledger}/transaction
+    - selector: bdware.bdledger.api.Query.GetTransactionByBlockHashAndIndex
+      get: /v0/ledgers/{ledger}/block/transaction
+    - selector: bdware.bdledger.api.Query.GetTransactions
+      post: /v0/ledgers/{ledger}/transactions/query
+      body: "*"
+    - selector: bdware.bdledger.api.Query.CountTransactions
+      post: /v0/ledgers/{ledger}/transactions/count
+      body: "*"
+
+
+
+

Note

+

Request/Response data of bytes type should/will be encoded with +Base64.

+
+
+

Note

+

When using hash strings in URL, they need to be encoded with +encodeURIComponent.

+
+
+

Request Examples {#_request_examples}

+
+

Node.ClientVersion {#_node_clientversion}

+

Get BDLedger node version

+
GET http://{{IP}}:{{PORT}}/v0/node/version
+
+
+

Response.

+
{
+  "version": "dev-210119.a88bf4eb"
+}
+
+
+
+
+

Ledger.CreateLedger {#_ledger_createledger}

+

Create a new ledger

+
POST http://{{IP}}:{{PORT}}/v0/ledgers
+
+
+

Request body.

+
{
+  "name": "test"
+}
+
+
+

Response.

+
{
+  "ok": true
+}
+
+
+
+
+

Ledger.GetLedgers {#_ledger_getledgers}

+

Get all ledgers

+
GET http://{{IP}}:{{PORT}}/v0/ledgers
+
+
+

Response.

+
{
+  "ledgers": [
+    "default",
+    "test"
+  ]
+}
+
+
+
+
+

Ledger.SendTransaction {#_ledger_sendtransaction}

+

Send a new transaction

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions
+
+
+

Request body.

+
{
+  "transaction": {
+    "type": 0,
+    "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+    "nonce": 52,
+    "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+  }
+}
+
+
+

Response.

+
{
+  "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+}
+
+
+
+
+

Query.GetBlockByHash {#_query_getblockbyhash}

+

Get a block identified by its hash

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block?hash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D
+
+
+

hash has to be encoded with +encodeURIComponent

+

Response.

+
{
+  "block": {
+    "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+    "creator": "",
+    "nonce": "0",
+    "parentHashes": [
+      "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+      "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+      "3XkwkuMBearq8uavN76Te7Zdpl8="
+    ],
+    "witnesses": [],
+    "timestamp": "1611038043",
+    "size": "0",
+    "transactionCount": 1,
+    "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+    "transactions": [
+      {
+        "blockHash": "",
+        "blockTimestamp": "0",
+        "index": 0,
+        "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+        "type": "RECORD",
+        "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+        "nonce": "0",
+        "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+        "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+      }
+    ],
+    "transactionHashes": [
+      "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+    ]
+  }
+}
+
+
+
+
+

Query.GetBlocks {#_query_getblocks}

+

Get blocks in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/query
+
+
+
enum IncludeTransactions {
+  NONE = 0; // Don't include transaction data
+  HASH = 1; // Include transactions hashes
+  FULL = 2; // Include full transactions
+}
+
+
+

Requirement: asciimath:[“start_timestamp”⇐”end_timestamp”]

+

If only end_timestamp is not specified, or +asciimath:[“end_timestamp”-“start_timestamp”>”query.maxDuration”], +then end_timestamp will be set to +asciimath:[“start_timestamp”+”query.maxDuration”].

+

If only start_timestamp is not specified, then start_timestamp +will be set to asciimath:[“end_timestamp”-“query.maxDuration”].

+

In all cases, start_timestamp will never be earlier than the +genesis block’s timestamp, and end_timestamp will never be later +than the current timestamp when the node process the query request.

+

Request body 1.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000,
+  "include_transactions": 0
+}
+
+
+

Response 1.

+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [],
+      "transactionHashes": []
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+

Request body 2.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000,
+  "include_transactions": 1
+}
+
+
+

Response 2.

+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [],
+      "transactionHashes": [
+        "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+      ]
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+

Request body 3.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000,
+  "include_transactions": 2
+}
+
+
+

Response 3.

+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [
+        {
+          "blockHash": "",
+          "blockTimestamp": "0",
+          "index": 0,
+          "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+          "type": "RECORD",
+          "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+          "nonce": "0",
+          "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+          "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+        }
+      ],
+      "transactionHashes": [
+        "VQBeA5Ee0Y5hqEileoQuYMHbOSE="
+      ]
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+

Query.CountBlocks {#_query_countblocks}

+

Count all blocks in a ledger, or blocks in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/count
+
+
+

Requirement: asciimath:[“start_timestamp”⇐”end_timestamp”]

+

If neither start_timestamp nor end_timestamp is specified, +then count all blocks in the specified ledger.

+

If only end_timestamp is not specified, then count all blocks with +timestamps later than start_timestamp.

+

If only start_timestamp is not specified, then count all blocks +with timestamps earlier than end_timestamp.

+

In all cases, start_timestamp will never be earlier than the +genesis block’s timestamp, and end_timestamp will never be later +than the current timestamp when the node process the query request.

+

Request body 1.

+
{}
+
+
+

Response 1.

+
{
+  "count": "5",
+  "startTimestamp": "0",
+  "endTimestamp": "1611039957"
+}
+
+
+

Request body 2.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000
+}
+
+
+

Response 2.

+
{
+  "count": "1",
+  "startTimestamp": "1611038000",
+  "endTimestamp": "1611039000"
+}
+
+
+
+
+

Query.GetRecentBlocks {#_query_getrecentblocks}

+

Get recent count blocks (Only support IncludeTransactions=NONE for +now)

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/blocks/recent?count=2
+
+
+

Response.

+
{
+  "blocks": [
+    {
+      "hash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8="
+      ],
+      "witnesses": [],
+      "timestamp": "1611038043",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "transactions": [],
+      "transactionHashes": []
+    },
+    {
+      "hash": "rk0DWMaUpRG82yVX+cFhbfhPFdw=",
+      "creator": "",
+      "nonce": "0",
+      "parentHashes": [
+        "fLX5pMY8M1qSAGZdKT1rWBkdEMo=",
+        "3XkwkuMBearq8uavN76Te7Zdpl8=",
+        "8pZPR74OALIbps5XFb4dL/s0j0M="
+      ],
+      "witnesses": [],
+      "timestamp": "1610968019",
+      "size": "0",
+      "transactionCount": 1,
+      "transactionsRoot": "LuxttCm/pSHVMOKF0sJExk+DJXc=",
+      "transactions": [],
+      "transactionHashes": []
+    }
+  ],
+  "startTimestamp": "1610968019",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+

Query.GetTransactionByHash {#_query_gettransactionbyhash}

+

Get a transaction identified by its hash

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/transaction?hash=VQBeA5Ee0Y5hqEileoQuYMHbOSE%3D
+
+
+

hash has to be encoded with +encodeURIComponent

+

Response.

+
{
+  "transaction": {
+    "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+    "blockTimestamp": "1611038043",
+    "index": 0,
+    "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+    "type": "RECORD",
+    "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+    "nonce": "0",
+    "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+    "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+  }
+}
+
+
+
+
+

Query.GetTransactionByBlockHashAndIndex {#_query_gettransactionbyblockhashandindex}

+

Get a transaction identified by hash of the block it belongs to and its +index inside the block

+
GET http://{{IP}}:{{PORT}}/v0/ledgers/test/block/transaction?blockHash=LSKr%2BK079Ax%2BrKdlyYN5ze2YGzo%3D&index=0
+
+
+

blockHash has to be encoded with +encodeURIComponent

+

Response.

+
{
+  "transaction": {
+    "blockHash": "LSKr+K079Ax+rKdlyYN5ze2YGzo=",
+    "blockTimestamp": "1611038043",
+    "index": 0,
+    "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+    "type": "RECORD",
+    "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+    "nonce": "0",
+    "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+    "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+  }
+}
+
+
+
+
+

Query.GetTransactions {#_query_gettransactions}

+

Get transactions in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/query
+
+
+

start_timestamp and end_timestamp follow the same requirements +and rules as in ???.

+

Request body.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000
+}
+
+
+

Response.

+
{
+  "transactions": [
+    {
+      "blockHash": "",
+      "blockTimestamp": "0",
+      "index": 0,
+      "hash": "VQBeA5Ee0Y5hqEileoQuYMHbOSE=",
+      "type": "RECORD",
+      "from": "8A3K/vANyv7wDcr+8A3K/vANyv4=",
+      "nonce": "0",
+      "to": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
+      "data": "lQItWZKS5hlUn6V/DMKKwvZXxvM="
+    }
+  ],
+  "startTimestamp": "1611038043",
+  "endTimestamp": "1611038043"
+}
+
+
+
+
+

Query.CountTransactions {#_query_counttransactions}

+

Count all transactions in a ledger, or transactions in a timestamp range

+
POST http://{{IP}}:{{PORT}}/v0/ledgers/test/transactions/count
+
+
+

start_timestamp and end_timestamp follow the same requirements +and rules as in ???.

+

Request body 1.

+
{}
+
+
+

Response 1.

+
{
+  "count": "4",
+  "startTimestamp": "0",
+  "endTimestamp": "1611039957"
+}
+
+
+

Request body 2.

+
{
+  "start_timestamp": 1611038000,
+  "end_timestamp": 1611039000
+}
+
+
+

Response 2.

+
{
+  "count": "1",
+  "startTimestamp": "1611038000",
+  "endTimestamp": "1611039000"
+}
+
+
+
+
+ + +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/doc/objects.inv b/doc/objects.inv new file mode 100644 index 0000000..15f2173 Binary files /dev/null and b/doc/objects.inv differ diff --git a/doc/search.html b/doc/search.html new file mode 100644 index 0000000..2e94f89 --- /dev/null +++ b/doc/search.html @@ -0,0 +1,228 @@ + + + + + + + + + + 搜索 — 北大数瑞大数据区块链 V1.0 文档 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
    + +
  • »
  • + +
  • 搜索
  • + + +
  • + +
  • + +
+ + +
+
+
+
+ + + + +
+ +
+ +
+ +
+
+ +
+ +
+

+ © 版权所有 2021, Peking University. + +

+
+ + + + 利用 Sphinx 构建,使用了 + + 主题 + + 由 Read the Docs开发. + +
+
+
+ +
+ +
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/searchindex.js b/doc/searchindex.js new file mode 100644 index 0000000..5d15fd7 --- /dev/null +++ b/doc/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["ContractAPI","IDEUsage","InstallTips","Introduction","YJSAPI","YJSInDepth","index","markdown/ContractAPI","markdown/IDEUsage","markdown/InstallTips","markdown/Introduction","markdown/YJSAPI","markdown/YJSInDepth","markdown_BDWare/ContractAPI","markdown_BDWare/IDEUsage","markdown_BDWare/InstallTips","markdown_BDWare/Introduction","markdown_BDWare/YJSAPI","markdown_BDWare/YJSInDepth","markdown_BDWare/httpapi"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["ContractAPI.rst","IDEUsage.rst","InstallTips.rst","Introduction.rst","YJSAPI.rst","YJSInDepth.rst","index.rst","markdown/ContractAPI.md","markdown/IDEUsage.md","markdown/InstallTips.md","markdown/Introduction.md","markdown/YJSAPI.md","markdown/YJSInDepth.md","markdown_BDWare/ContractAPI.md","markdown_BDWare/IDEUsage.md","markdown_BDWare/InstallTips.md","markdown_BDWare/Introduction.md","markdown_BDWare/YJSAPI.md","markdown_BDWare/YJSInDepth.md","markdown_BDWare/httpapi.md"],objects:{},objnames:{},objtypes:{},terms:{"###":[1,8,14],"####":[1,4,8,11,14,17],"#####":4,"++":[4,5,11,12,17,18],"--":[0,4,7,11,13,17],"..":[4,11],"...":[0,4,7,11,13,17],"....":[4,11,17],"..._":[0,7,13],"0.00":[0,7,13],"0.01":[0,7,13],"0.03":[0,7,13],"0.1":[0,4,7,11,13,17],"00":[0,7,13],"01s":[0,7,13],"02":[0,7,13],"02.10":[0,7,13],"03":[0,7,13],"03s":[0,7,13],"040461417efe01423ba603f71c689387e8aac4aa2a6f7cddfaf22c1d22c40222f7669a054e7ec2e8533b04ccbc7a0e6655ac4ae4acef81a2b1822ec6cabcaf6c1f":[0,7,13],"0431":[0,7,13],"0431e31":[0,7,13],"0431e311":[0,7,13],"0431e311bd708":[0,7,13],"0431e311bd70840fe69965e2cabea97fafe99f2133953c01abb9bd7cb62af42f8283f474d203051e920d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d":[0,7,13],"04405d7b":[0,7,13],"04405d7ba358d9234939623ab51ea94ca685e6a1f36ed81fd9630ccba6473e632f163bb30faffd4c91f21e5bace20101d6d6e36c04ac67eea14cc24b4962b84f57":[0,7,13],"04541429c11b094":[0,7,13],"0470b2f27f4f6":[0,7,13],"0475c7b061":[0,7,13],"0475c7b061f32477c1e228dd04143daf58a5574dc3f6b02bd2857cc794eb92bfe98606dc314049e77fd8714f57a5a481cb470cc759e688fe60d40fc87092165e55":[0,7,13],"0475d34rf3434":[0,7,13],"0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba3":[0,7,13],"0480204f4ef341359a5f64fcb11baf9ca2e6706ac20cba36ca83066870cf2c1d5de6df67e24e68dde7934af9b31d94a6084281db3d32d5ce42ab8f75bf799aca05":[0,7,13],"0492d974b8a5b473d0ed2c81800917f76e2a1ec3666067888c85fe6922a672223f2083f95402ae13a744df58deabbe7206c4a317dd14296b0d3941a26ca4e34dc5":[0,7,13],"049999ebd14ff3b96ebf7f7325e1da94a1c4c376573a1dc1cec2b4f7a3b09ed7b07252134e93b6ac2e1853268b82f4b541d34fb42b0182cd61043e99d3489e2cf7":[0,7,13],"04aadcc7103c":[0,7,13],"04aadcc7103cd02626d228affbef53f8242eca4ddd6f179d30b622440666715cfbb6fd1d3678a2b25812dea9917073e79a65f7ade517f784dc76288efceb37ecaa1025e6903540702f729da1c2eccd93f4e6fafce40df443e7fd74387169d0c6d927c7bb12882d0471c8d3e6f31b0316a42fc38f6dd9978d4351b23b2ad63e2244909e98f51185d32cb99b4ae4e22d3ab4c04027bb":[0,7,13],"04b00f32eab70c78d1b43738f190d326d36c021af2124acefe6d057016b11ea31c750bb473e565c9d89e4993a44f4d30adf447d3026a21ff4b3b64cef523074ef7":[0,7,13],"04bf52213343c147e631b877bceb17b794230ee551e85f58fa429c4ba03d690778cc384c6916c63df36cb9e35c7e274fdb4e18491dfe3d611d347856d441cacc5af9090b515f02afc2dfbf56461ec83b5a4cd342466360d6cf82e6e40b637430ac4a329ccbc798daf7d526af9e3b3600e0bea1bfab8c160ef90128faf67b19e45f37664f1e4b":[0,7,13],"04c4c855862b53f323e077ccfcc744ecc2c0a04645ed16d99ede8fd5866b38c0670a97ad22c6260d1a4672aba2a5fe229a2d4eba34627c054aab102620afa288c1":[0,7,13],"04d1924329f72ced148f6f333fb985ccbaa31b1e3aacf10be5f43d4a4ff5ad88899a005e79e37fc06993e1d66ada8cf8b711cb36f59538bb7d3e39e70fa9360ddd":[0,7,13],"04eafad549d0757cf67f360815e15e157c7428c9ea9fb933f31a5d45bfb6edd9809c5bf6a5f37d7b817207f19fb2d76b7dbdefe38084cd3282e37b9ac39959dfab":[0,7,13],"06":[0,7,13],"07":[0,7,13],"07.16":[0,7,13],"08":[0,7,13],"09":[0,7,13],"09%":[0,7,13],"0987654321ab":[0,7,13],"09b4f06d":[0,7,13],"09export":[0,7,13],"09export%":[0,7,13],"09return":[0,7,13],"09return%":[0,7,13],"0a":[0,7,13],"0a%":[0,7,13],"0l":[5,12,18],"0x3034643139323433323966373263656431343866":[0,7,13],"0x65786563757465436f6e74726163740000000000":[0,7,13],"1.0":[0,5,7,12,13,18],"1.8":[0,2,7,9,13,15],"10":[0,3,7,10,13],"100":[0,4,7,11,13,17],"100.00%":[0,7,13],"1000":[0,2,4,7,9,11,13,15,17],"104":[0,7,13],"108":[0,7,13],"11":[0,3,7,10,13],"1187":[0,7,13],"12":[0,3,7,10,13],"123456":[0,7,13],"127":[0,4,7,11,13,17],"127.0":[0,4,7,11,13,17],"13":[0,3,7,10,13],"131":[0,7,13],"1382208250":[0,7,13],"14":[0,3,7,10,13],"14.19":[0,7,13],"15":[0,7,13],"1543583350":[0,7,13],"1544":[0,7,13],"1572335939893":[0,7,13],"1583139323822":[0,7,13],"1583141525539":[0,7,13],"1583410158761":[0,7,13],"1587398989914":[0,7,13],"1596758400000":[0,7,13],"1597296300272":[0,7,13],"1597296301030":[0,7,13],"1597296305745":[0,7,13],"1597296305746":[0,7,13],"1597296305747":[0,7,13],"1597296305751":[0,7,13],"1597296305842":[0,7,13],"1597296305868":[0,7,13],"1597296305893":[0,7,13],"1597296305908":[0,7,13],"1597296314629":[0,7,13],"1597296314629_6067":[0,7,13],"1597296314654":[0,7,13],"1597296314655":[0,7,13],"1597296314658":[0,7,13],"1597376006438":[0,7,13],"1597376006441":[0,7,13],"1597376006444":[0,7,13],"1597376006448":[0,7,13],"1597376006449":[0,7,13],"16":[0,3,7,10,13],"160":[0,7,13],"1610968019":[13,19],"1611038000":[13,19],"1611038043":[13,19],"1611039000":[13,19],"1611039957":[13,19],"1615":[0,7,13],"1617":[0,7,13],"1617178709933":[0,7,13],"1617206735696":[0,7,13],"1617211077264":[0,7,13],"1617211077264_223":[0,7,13],"1617254937373":[4,11,17],"1626":[0,7,13],"1627":[0,7,13],"1630":[0,7,13],"1631":[0,7,13],"1632":[0,7,13],"165":[0,7,13],"1658407837":[0,7,13],"168":[0,4,7,11,13,17],"17":[0,7,13],"17.20":[0,7,13],"1717":[0,7,13],"1718":[0,2,7,9,13,15],"1719":[0,7,13],"173":[0,7,13],"1759263594":[0,7,13],"177":[0,7,13],"1783453207480410":[4,11,17],"18":[0,7,13],"180":[0,7,13],"18000":[0,7,13],"18001":[0,7,13],"18002":[0,7,13],"18090":[0,7,13],"18091":[0,4,7,11,13,17],"1809139":[0,7,13],"1809139.104":[0,7,13],"182":[0,7,13],"182.173":[0,7,13],"19":[0,3,7,10,13],"192":[0,4,7,11,13,17],"192.168":[0,4,7,11,13,17],"1cb855f1ecec11":[0,7,13],"2.0":[3,10,16],"2.1":[0,7,13],"2.3":[0,7,13],"20":[0,5,7,12,13,18],"20%":[0,7,13],"201":[0,7,13],"201.21040":[0,7,13],"201.40":[0,7,13],"2018":[0,3,7,10,13],"2019":[3,10],"2020":[0,3,7,10,13],"2021":[0,3,7,10,13],"2023975189":[0,7,13],"203156239086062402":[0,7,13],"2073401446":[0,7,13],"208":[0,7,13],"20arg":[0,7,13],"20function":[0,7,13],"20function%":[0,7,13],"20main":[0,7,13],"20shortc":[0,7,13],"20shortc%":[0,7,13],"21":[0,3,7,10,13],"210119":[13,19],"21031":[0,7,13],"21032":[0,7,13],"21040":[0,7,13],"21042":[0,7,13],"22":[0,3,7,10,13],"22%":[0,7,13],"223":[0,7,13],"22eventpub":[0,7,13],"22eventsub":[0,7,13],"22licencemanag":[0,7,13],"23":[0,7,13],"23.18":[0,7,13],"2390672423847654148":[0,7,13],"24":[0,4,7,11,13],"24.16":[0,7,13],"24.18":[0,7,13],"24.20":[0,7,13],"24.21":[0,7,13],"240":[0,7,13],"247":[0,7,13],"247.70":[0,7,13],"247468535":[0,7,13],"248":[0,7,13],"248.208":[0,7,13],"249":[0,7,13],"249.131":[0,7,13],"2493":[0,7,13],"2496":[0,7,13],"25":[0,3,7,10,13],"25.21":[0,7,13],"26":[0,3,7,10,13],"27":[0,3,7,10,13],"28":[0,7,13],"28.15":[0,7,13],"28.20":[0,7,13],"28.21":[0,7,13],"28.22":[0,7,13],"29":[0,7,13],"2bk079ax":[13,19],"2bk079ax%":[13,19],"2brkdlyyn5ze2ygzo":[13,19],"2brkdlyyn5ze2ygzo%":[13,19],"2c":[0,7,13],"2c%":[0,7,13],"2c72231a6daa078a3ce657c0a2ed38251b7db56cf725beaf86780d4c240b19ccc2":[0,7,13],"3.2":[0,7,13],"3.4":[4,11,17],"3.76":[0,7,13],"30":6,"3045022004ffd1346b936196f5b13953d2f3e11823a0d0a2d2f6fecea258cef8e20d99c0022100bbc219ed1f56799ba28a763b9e9e47063164e7ceecfbfa752de42f44551ffb83":[0,7,13],"3045022075c7268e888b0efdef167a3f4dfc6589d771c6be41b3c0a1dc12d057e811f395022100d44f460d0cc3643e169ef08231e75a1e895646c53295c0ef1d15c3b462a53d6b":[0,7,13],"31":[0,3,7,10,13],"32":[0,7,13],"32.00":[0,7,13],"34":[0,7,13,17],"3437513873417136535":[0,7,13],"345343rr3f34":[0,7,13],"35":[3,10],"36":[0,7,13],"3600":[0,7,13],"36097783842688":[4,11,17],"37":[0,7,13],"38":[0,7,13],"382r0934309t":[0,7,13],"387355870552374748":[0,7,13],"3882409580676458151":[0,7,13],"39":[0,7,13],"39.104":[0,7,13],"39.108":[0,7,13],"3a6c60621907146b77146c1f2d48700e47520173":[0,7,13],"3b":[0,7,13],"3b%":[0,7,13],"3d":[13,19],"3r729hf2ehf982":[0,7,13],"3xkwkumbearq8uavn76te7zdpl8":[13,19],"3zlc":[4,11,17],"4.4":[4,11,17],"40":[0,7,13],"40009b4f06d":[0,7,13],"4063665700873624164":[0,7,13],"41":[0,7,13],"42":[0,7,13],"43":[0,7,13,17],"4310212972071102":[4,11,17],"45":[0,3,7,10,13],"4551":[0,7,13],"4580":[0,7,13],"46":[0,7,13],"47":[0,7,13],"47.98":[0,7,13],"470":[0,4,7,11,13,17],"4772693258708933626":[0,7,13],"48":17,"49":[0,7,13],"4959947809200104526":[0,7,13],"4959947809200104526_session":0,"4c2cef1756b2b591ab7eead19d67331e2294c7ba765c72298733c306ada0b6e84afbb6c7b9dba48b9843236ebe67aecb4af09fe58a51eef0e2e89b9f3e5cad02":[0,7,13],"4d3b75750835092a50085127702669615b602e53":[4,11,17],"50":17,"5000":[0,4,7,11,13,17],"506393888":[0,7,13],"51":[0,7,13],"52":[13,19],"528822126":[0,7,13],"53":[0,7,13],"54":[0,7,13],"55":[0,7,13],"56":[0,7,13],"56.12":[0,7,13],"56.240":[0,7,13],"562752842":[0,7,13],"57":[0,7,13],"58":[0,7,13],"5b":[0,7,13],"5b%":[0,7,13],"5d":[0,7,13],"6056586201629372511":[0,7,13],"6067":[0,7,13],"6161":[4,11,17],"620602333":[0,7,13],"6425375229108830572":[0,7,13],"65051856":[0,7,13],"650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4":[0,7,13],"650d3cad50509682937c253d84da99230e8ea1bcfb9b10f6d18f8888c7c4b6b4%":[0,7,13],"656564":[0,7,13],"656565":[0,7,13],"65e55":[0,7,13],"65e55_4063665700873624164":[0,7,13],"6602401010405792959":[0,7,13],"666":[4,11,17],"70":[0,7,13],"70.160":[0,7,13],"7006776427870311552":[0,7,13],"7241":[0,7,13],"7245":[0,7,13],"732":[0,7,13],"7357":[0,7,13],"7541":[0,7,13],"7548":[0,7,13],"7555":[0,7,13],"7561786202695627022":[0,7,13],"7584":[0,7,13],"7585":[0,7,13],"7591":[0,7,13],"7598":[0,7,13],"76":[0,7,13,17],"7604666709899222357":[0,7,13],"7609":[0,7,13],"761":[0,7,13],"7612":[0,7,13],"77":[0,7,13],"77.165":[0,7,13],"7766580783668916":[4,11,17],"78":[3,10],"7b":[0,7,13],"7b%":[0,7,13],"7d":[0,7,13],"7d%":[0,7,13],"8.0":[4,11],"8003529429500512736":[0,7,13],"8080":[2,9,15],"814046805":[0,7,13],"83":[0,7,13],"8440":[0,7,13],"8442":[0,7,13],"8444":[0,7,13],"845581788":[0,7,13],"849660532962309239":[0,7,13],"8521":[0,7,13],"8590335427581967208":[0,7,13],"86":[0,4,7,11,13,17],"86.5000":[0,4,7,11,13,17],"86400000":[0,7,13],"8a3k":[13,19],"8b7ff78aa631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275":[0,7,13],"8pzpr74oalibps5xfb4dl":[13,19],"8u271":[2,9,15],"8uxxxxx":[2,9,15],"90":[3,10],"912":[0,7,13],"943728900":[0,7,13],"95":[3,10],"97":[3,10],"9782323":[0,7,13],"9782323_session":[0,7,13],"98":[0,7,13],"99":[3,10],"\u4e00\u4e2a":[1,2,3,4,5,8,9,10,11,12,14,15,16,17,18],"\u4e00\u4e9b":[1,8,14],"\u4e00\u5171":[1,8,14],"\u4e00\u5207":[1,8,14],"\u4e00\u5b9a":[5,12,18],"\u4e00\u6b21":[0,1,3,4,7,8,10,11,13,14],"\u4e00\u7cfb":[0,7,13],"\u4e00\u7cfb\u5217":[0,7,13],"\u4e00\u7ec4":[2,9,15],"\u4e00\u81f3":[2,9,15],"\u4e00\u822c":[2,9,15],"\u4e09\u4e2a":[1,4,5,8,11,12,14,17,18],"\u4e09\u79cd":[2,9,15],"\u4e0a\u4f20":[3,4,10,11],"\u4e0a\u89d2":[1,2,8,9,14,15],"\u4e0a\u8ff0":[2,4,9,11,15,17],"\u4e0a\u9762":[4,11,17],"\u4e0b\u56fe":[2,9,15],"\u4e0b\u65b9":[1,8,14],"\u4e0b\u8f7d":[1,6,8,14],"\u4e0b\u8f7d\u5b89\u88c5":[2,9,15],"\u4e0b\u9762":[0,1,7,8,13,14],"\u4e0d\u4f1a":[1,8,14],"\u4e0d\u540c":[1,8,14],"\u4e0d\u5e26":[4,11],"\u4e0d\u662f":[1,4,8,11,14,17],"\u4e0d\u80fd":[1,2,3,8,9,10,14,15],"\u4e0d\u8bba":[0,7,13],"\u4e0d\u8bba\u662f":[0,7,13],"\u4e0d\u8db3":[3,10],"\u4e0e\u975e":6,"\u4e24\u4e2a":[4,11,17],"\u4e24\u5929":[1,8,14],"\u4e24\u65e5":[1,8,14],"\u4e24\u79cd":[4,5,11,12,17,18],"\u4e24\u7c7b":[0,7,13],"\u4e24\u7ec4":[2,9,15],"\u4e2a\u4eba":[1,8,14],"\u4e2a\u6570":[4,11,17],"\u4e2d\u5fc3":[1,2,3,6,8,9,10,14,15],"\u4e2d\u5fc3\u5316":[3,10],"\u4e2d\u6587":[4,11],"\u4e2d\u6709":[1,4,5,8,11,12,14,17,18],"\u4e2d\u95f4":[4,11,17],"\u4e3a\u7a7a":[0,7,13],"\u4e3a\u8868\u540d":[4,11,17],"\u4e3b\u8981":[1,8,14],"\u4e3b\u9875":[5,12,18],"\u4e3b\u9898":6,"\u4e4b\u5185":[1,8,14],"\u4e4b\u540e":[1,2,8,9,14,15],"\u4e4b\u95f4":[0,2,4,7,9,11,13,15,17],"\u4e71\u7801":[4,11,17],"\u4e86\u89e3":[4,11,17],"\u4e8b\u4ef6":[1,3,6,8,10,14],"\u4e8b\u5148":[4,11],"\u4e8c\u4e2a":[4,5,11,12,17,18],"\u4e8c\u7ec4":[2,9,15],"\u4e94\u4f4d":[1,8,14],"\u4ea6\u53ef":[2,9,15],"\u4ea7\u751f":[1,8,14],"\u4ec0\u4e48":6,"\u4ec5\u5f53":[4,11,17],"\u4ecb\u7ecd":[4,6,11,17],"\u4ece\u800c":[1,8,14],"\u4ee3\u66ff":[0,7,13],"\u4ee3\u7801":[2,3,4,6,9,10,11,15,16,17],"\u4ee5\u4e0a":[1,4,8,11,14,17],"\u4ee5\u4e0b":[0,1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18],"\u4ee5\u4fbf":[0,5,7,12,13,18],"\u4ee5\u53ca":[1,8,14],"\u4ee5\u540e":[5,12,18],"\u4eea\u8868":6,"\u4eea\u8868\u76d8":6,"\u4ef6\u5939":[0,4,7,11,13,17],"\u4efb\u610f":[0,4,5,7,11,12,13,17,18],"\u4f18\u5316":[3,10],"\u4f20\u5165":[0,4,7,11,13,17],"\u4f20\u5230":[4,11],"\u4f4d\u7f6e":[4,11,17],"\u4f5c\u4e3a":[3,4,10,11,16,17],"\u4f5c\u7528":[3,10],"\u4f7f\u5f97":[1,5,8,12,14,18],"\u4f7f\u7528":[0,5,6,7,12,13,18],"\u4f7f\u7528\u8005":[0,1,7,8,13,14],"\u4f8b\u5982":[2,4,5,9,11,12,15,17,18],"\u4f9b\u8005":[0,1,7,8,13,14],"\u4f9d\u8d56":[5,6,12,18],"\u4fdd\u5b58":[1,4,8,11,14,17],"\u4fdd\u7559":[2,9,15],"\u4fdd\u8bc1":[0,3,7,10,13,16],"\u4fe1\u606f":[2,4,5,6,9,11,12,15,17,18],"\u4fee\u590d":[3,10],"\u4fee\u6539":[1,2,3,4,8,9,10,11,14,15,17],"\u4fee\u9970":[4,5,11,12,17,18],"\u505c\u6b62":6,"\u5143\u7d20":[4,11,17],"\u5143\u90a6":[4,11,17],"\u5143\u90a6\u4e14":[4,11,17],"\u5168\u540d":[4,11],"\u5168\u5c40":[5,12,18],"\u5168\u5c40\u53d8\u91cf":[5,12,18],"\u5168\u90e8":6,"\u516c\u79c1":[0,1,2,4,7,8,9,11,13,14,15,17],"\u516c\u94a5":[0,1,4,5,7,8,11,12,13,14,17,18],"\u516d\u4e2a":[1,8,14],"\u516d\u7c7b":[1,8,14],"\u5173\u4e8e":[1,4,8,11,14,17],"\u5173\u952e":[1,5,8,12,14,18],"\u5173\u952e\u5b57":[5,12,18],"\u5173\u952e\u8bcd":[1,8,14],"\u5173\u95ed":[1,8,14],"\u5176\u4e2d":[0,1,2,4,7,8,9,11,13,14,15,17],"\u5176\u4ed6":[1,2,4,5,8,9,11,12,14,15,17,18],"\u5177\u4f53":[2,5,9,12,15,18],"\u5185\u542b":[4,11,17],"\u5185\u5b58":[1,2,3,8,9,10,14,15],"\u5185\u5b58\u4e0d\u8db3":[3,10],"\u5185\u5bb9":[0,4,6,7,11,13,17],"\u5185\u7f6e":[0,5,6,7,12,13,18],"\u5185\u90e8":[4,11,17],"\u5197\u4f59":[3,10,16],"\u5199\u6cd5":[4,11,17],"\u51b3\u5b9a":[5,12,18],"\u51c6\u5165":6,"\u51e0\u4e2a":[0,7,13],"\u51e0\u79cd":[5,12,18],"\u51fd\u6570":[0,1,3,6,7,8,10,13,14,16,17],"\u5206\u4e3a":[0,1,4,5,7,8,11,12,13,14,17,18],"\u5206\u522b":[1,8,14],"\u5206\u53d1":[3,10],"\u5206\u5e03":6,"\u5206\u652f":[4,11,17],"\u5206\u6790":[3,10,16],"\u5206\u7c7b":[0,6,7,13],"\u5206\u914d":[3,4,10,11,17],"\u5206\u9694":[5,12,18],"\u5206\u9694\u7b26":[5,12,18],"\u5207\u6362":[2,9,15],"\u5212\u5206":6,"\u5217\u53d6":[0,7,13],"\u5217\u8868":6,"\u521b\u5efa":[0,4,6,7,11,13,17],"\u521b\u5efa\u8005":[1,8,14],"\u521d\u6b65":[3,10],"\u5220\u9664":[4,11,17],"\u5230\u671f":[1,8,14],"\u5237\u65b0":[1,8,14],"\u524d\u7aef":[2,3,6,9,10,15,16],"\u524d\u7f00":[0,3,7,10,13],"\u529f\u80fd":[0,2,7,9,13,15],"\u52a0\u5165":[1,2,8,9,14,15],"\u52a0\u5bc6":[0,2,7,9,13,15],"\u52a0\u89e3\u5bc6":6,"\u52a0\u8f7d":[0,6,7,13,17],"\u52a1\u5668":[0,2,7,9,13,15],"\u52a8\u6001":[0,1,3,5,7,8,10,12,13,14,18],"\u52a8\u6001\u5206\u6790":[0,1,7,8,13,14],"\u5305\u542b":[2,3,4,5,9,10,11,12,15,17,18],"\u5305\u6210":[5,12,18],"\u5305\u62ec":[0,1,4,5,7,8,11,12,13,14,17,18],"\u5305\u88c5":[0,7,13],"\u5317\u5927":[3,10],"\u533a\u522b":[5,12,18],"\u533a\u57df":[1,8,14],"\u533f\u540d":[0,7,13],"\u5347\u7ea7":[3,6,10],"\u534f\u8bae":[0,7,13],"\u5355\u4e2a":[2,9,15],"\u5355\u5143":[5,12,18],"\u5355\u70b9":[1,8,14],"\u5355\u72ec":[2,9,15],"\u5355\u884c":[5,12,18],"\u5355\u8bcd":[4,11],"\u5360\u7528":[1,8,14],"\u5373\u53ef":[1,8,14],"\u538b\u529b":[3,10],"\u53c2\u6570":[1,5,8,12,14,18],"\u53c2\u8003":[0,4,5,6,7,11,12,13,17,18],"\u53cc\u5f15\u53f7":[1,8,14],"\u53cd\u4e4b":[1,8,14],"\u53cd\u5c04":[4,11,17],"\u53d1\u5e03":[3,5,6,10,12,18],"\u53d1\u5e03\u8005":[5,12,18],"\u53d1\u7ed9":[1,8,14],"\u53d1\u8d77":[0,4,7,11,13,17],"\u53d1\u8d77\u8005":[0,7,13],"\u53d1\u9001":[0,7,13],"\u53d6\u6d88":[1,8,14],"\u53d8\u91cf":[4,11,17],"\u53d8\u91cf\u503c":[5,12,18],"\u53e3\u53f7":[0,4,7,11,13,17],"\u53ea\u6709":[3,4,5,10,11,12,17,18],"\u53ea\u80fd":[4,5,11,12,17,18],"\u53ea\u8bfb":[4,11,17],"\u53ef\u4ee5":[0,1,3,4,5,7,8,10,11,12,13,14,16,17,18],"\u53ef\u4fe1":[2,3,6,9,10,15,16],"\u53ef\u4fe1\u8ba1\u7b97":[2,3,9,10,15,16],"\u53ef\u7528":[0,3,4,7,10,11,13,16,17],"\u53ef\u7528\u6027":[3,10,16],"\u53ef\u80fd":[1,3,4,8,10,11,14,17],"\u53ef\u89c1":[1,8,14],"\u53ef\u89c6":[0,2,7,9,13,15],"\u53ef\u89c6\u5316":[0,7,13],"\u53ef\u9009":[0,7,13],"\u53ef\u9009\u9879":[0,7,13],"\u53ef\u9760":[3,10,16],"\u53ef\u9760\u6027":[3,10,16],"\u53f3\u4e0a":[1,2,8,9,14,15],"\u53f3\u4e0a\u89d2":[1,2,8,9,14,15],"\u53f3\u4e0b":[1,8,14],"\u53f3\u4e0b\u65b9":[1,8,14],"\u53f3\u4fa7":[1,8,14],"\u5404\u4e2a":[2,9,15],"\u5404\u79cd":[3,5,10,12,16,18],"\u5404\u9879":[1,8,14],"\u5408\u7ea6":[3,5,6,10,12,16,18],"\u540c\u4e00":[1,2,5,8,9,12,14,15,18],"\u540c\u4e00\u4e2a":[1,8,14],"\u540c\u610f":[1,8,14],"\u540c\u65f6":[3,5,10,12,16,18],"\u540c\u6b65":[1,3,8,10,14],"\u540d\u5373":[4,11,17],"\u540d\u5b57":[0,7,13],"\u540d\u79f0":[1,3,4,5,8,10,11,12,14,16,17,18],"\u540e\u53f0":[3,10,16],"\u540e\u7eed":[0,4,7,11,13,17],"\u540e\u7f00":[4,11],"\u542b\u6709":[1,8,14],"\u542f\u52a8":[2,3,6,9,10,15],"\u542f\u7528":[3,10],"\u5468\u671f":[0,7,13],"\u547d\u4ee4":[0,2,7,9,13,15],"\u547d\u4ee4\u884c":[0,2,7,9,13,15],"\u547d\u540d":[5,12,18],"\u54c8\u5e0c":[0,4,7,11,13,17],"\u54cd\u5e94":[2,9,15],"\u552f\u4e00":[0,4,7,11,13,17],"\u552f\u4e00\u6027":[0,7,13],"\u56db\u4e2a":[1,4,8,11,14,17],"\u56db\u79cd":[1,8,14],"\u56db\u7c7b":[0,1,7,8,13,14],"\u56de\u590d":[0,7,13],"\u56de\u653e":[3,10],"\u56de\u8c03":[0,5,7,12,13,18],"\u56e0\u4e3a":[5,12,18],"\u56e0\u6b64":[4,11,17],"\u56fd\u5bc6":[3,10,16],"\u56fe\u5f0f":[2,9,15],"\u56fe\u8868":[3,10,16],"\u5728\u7ebf":[0,6,7,13],"\u5730\u533a":[4,11],"\u5730\u5740":[0,1,4,7,8,11,13,14,17],"\u573a\u666f":[3,10,16],"\u57df\u540d":[4,11,17],"\u57fa\u4e8e":[0,3,4,7,10,11,13,16,17],"\u586b\u5199":[1,8,14],"\u589e\u52a0":[0,3,7,10,13],"\u58f0\u660e":[4,6,11,17],"\u5904\u4e8e":[1,8,14],"\u5904\u7406":[3,5,10,12,18],"\u5904\u7406\u4e8b\u4ef6":[5,12,18],"\u5907\u4efd":[0,3,7,10,13],"\u590d\u5236":[1,2,4,8,9,11,14,15,17],"\u590d\u5236\u5230":[1,8,14],"\u591a\u4e2a":[2,3,9,10,15],"\u591a\u5c11":[1,8,14],"\u591a\u70b9":[1,3,8,10,14],"\u591a\u79cd":[3,10,16],"\u591a\u7ebf":6,"\u591a\u7ebf\u7a0b":6,"\u591a\u884c":[5,12,18],"\u591a\u9009":[1,8,14],"\u5927\u89c4":[2,9,15],"\u5927\u89c4\u6a21":[2,9,15],"\u5929\u5185":6,"\u5929\u6570":[1,8,14],"\u5931\u8d25":[1,4,8,11,14,17],"\u5982\u4e0b":[0,4,5,7,11,12,13,17,18],"\u5982\u4f55":[3,4,10,11,17],"\u5982\u60f3":[4,11,17],"\u5982\u679c":[0,1,2,4,7,8,9,11,13,14,15,17],"\u5982\u9700":[2,9,15],"\u59d3\u540d":[5,12,18],"\u5b57\u6bb5":[0,4,7,11,13,17],"\u5b57\u6bb5\u540d":[0,7,13],"\u5b57\u7b26":[0,4,5,7,11,12,13,17,18],"\u5b57\u7b26\u4e32":[0,4,5,7,11,12,13,17,18],"\u5b57\u8282":[3,4,10,11,16,17],"\u5b58\u50a8":[4,11,17],"\u5b58\u5728":[4,5,11,12,17,18],"\u5b58\u653e":[2,9,15],"\u5b58\u8bc1":[4,11,17],"\u5b89\u5168":[3,10,16],"\u5b89\u5168\u6027":[3,10,16],"\u5b89\u88c5":[4,6,11,17],"\u5b89\u88c5\u5305":[2,9,15],"\u5b8c\u5584":[3,10],"\u5b8c\u6210":[0,1,7,8,13,14],"\u5b9a\u4e49":[1,3,4,6,8,10,11,14,17],"\u5b9a\u6027":[3,10],"\u5b9a\u65f6":[3,10],"\u5b9e\u4f8b":[2,6,9,15],"\u5b9e\u73b0":[0,2,3,5,7,9,10,12,13,15,16,18],"\u5ba2\u6237":[0,2,3,4,5,7,9,10,11,12,13,15,17,18],"\u5ba2\u6237\u7aef":[0,2,3,4,5,7,9,10,11,12,13,15,17,18],"\u5bbd\u5ea6":[3,10],"\u5bc6\u7801":[0,4,7,11,13,17],"\u5bf9\u4e8e":[1,5,8,12,14,18],"\u5bf9\u51c6":[1,8,14],"\u5bf9\u5916":[2,9,15],"\u5bf9\u5e94":[0,1,4,7,8,11,13,14,17],"\u5bf9\u8c61":[5,6,12,18],"\u5bfc\u5165":[1,2,5,8,9,12,14,15,18],"\u5bfc\u5165\u5230":[5,12,18],"\u5bfc\u81f4":[3,10],"\u5c06\u4f1a":[1,8,14],"\u5c06\u8981":[5,12,18],"\u5c0f\u8282":[4,11,17],"\u5c1d\u8bd5":[3,10],"\u5c40\u90e8":[5,12,18],"\u5c40\u90e8\u53d8\u91cf":[5,12,18],"\u5c42\u9762":[5,12,18],"\u5c55\u793a":[1,3,8,10,14],"\u5de5\u4e1a":[0,7,13],"\u5de5\u5177":[2,3,5,6,9,10,12,15,18],"\u5de6\u4fa7":[1,2,8,9,14,15],"\u5de8\u4eba":[3,10,16],"\u5df2\u6709":[1,8,14],"\u5df2\u7ecf":[0,1,7,8,13,14],"\u5e03\u5c14":[0,4,7,11,13,17],"\u5e03\u5c14\u503c":[0,4,7,11,13],"\u5e26\u6709":[1,8,14],"\u5e2e\u52a9":[2,9,15],"\u5e73\u53f0":[3,4,10,11,16,17],"\u5e76\u4e14":[1,8,14],"\u5e8f\u5217":[4,11,17],"\u5e8f\u53f7":[4,11,17],"\u5e94\u7528":[3,6,10],"\u5e9f\u5f03":[0,7,13],"\u5efa\u7acb":6,"\u5f00\u53d1":[0,5,7,12,13,18],"\u5f00\u53d1\u8005":[0,5,7,12,13,18],"\u5f00\u5934":[4,11,17],"\u5f00\u59cb":[4,11,17],"\u5f00\u6e90":6,"\u5f02\u5e38":[4,11,17],"\u5f15\u5165":[4,11,17],"\u5f15\u53f7":[1,8,14],"\u5f15\u64ce":[2,3,5,9,10,12,15,18],"\u5f31\u5316":[3,10],"\u5f53\u524d":[5,6,12,18],"\u5f53\u7136":[5,12,18],"\u5f62\u5f0f":[4,11,17],"\u5f85\u9a8c":[4,11,17],"\u5fc3\u8df3":[3,10],"\u5fc5\u8981":[5,12,18],"\u5fc5\u987b":[0,4,5,7,11,12,13,17,18],"\u5ffd\u7565":[1,8,14],"\u603b\u6570":[0,7,13],"\u6062\u590d":[3,10],"\u60c5\u51b5":[0,2,6,7,9,13,15],"\u60f3\u6539":[1,8,14],"\u60f3\u8981":[1,8,14],"\u610f\u56fe":0,"\u611f\u8c22":[3,10,16],"\u6210\u4e3a":[0,1,4,7,8,11,13,14,17],"\u6210\u529f":[1,8,14],"\u6216\u662f":[0,7,13],"\u6216\u8005":[1,8,14],"\u6237\u540d":[0,4,7,11,13,17],"\u6237\u6570":[1,8,14],"\u6240\u5728":[1,4,8,11,14,17],"\u6240\u5c5e":[0,1,7,8,13,14],"\u6240\u6709":[1,2,3,5,8,9,10,12,14,15,18],"\u6240\u793a":[5,12,18],"\u624b\u52a8":[0,1,3,7,8,10,13,14],"\u624b\u673a":[4,11,17],"\u6253\u5305":[1,3,8,10,14],"\u6253\u5f00":[1,2,4,8,9,11,14,15,17],"\u6267\u884c":[3,5,6,10,12,16,18],"\u6298\u7ebf":[1,8,14],"\u6298\u7ebf\u56fe":[1,8,14],"\u629b\u51fa":[4,11,17],"\u62b5\u8d56":[2,9,15],"\u62d3\u6251":6,"\u62e5\u585e":[3,10],"\u62e5\u6709":[0,1,7,8,13,14],"\u6301\u4e45":[3,10],"\u6307\u4ee4":6,"\u6307\u5b9a":[1,4,8,11,14,17],"\u6309\u7167":[4,11,17],"\u636e\u5e93":[0,3,4,7,10,11,13,16,17],"\u6388\u6743":[4,6,11,17],"\u6392\u5e8f":[1,8,14],"\u6392\u7248":[3,10,16],"\u6392\u961f":[3,10],"\u63a5\u5165":[3,10,16],"\u63a5\u53d7":[4,11,17],"\u63a5\u53e3":[3,4,6,10,11,17],"\u63a5\u53e3\u9694\u79bb":[3,10],"\u63a7\u5236":[0,3,7,10,13,16],"\u63a7\u5236\u7b56\u7565":[0,3,7,10,13],"\u63cf\u8ff0":[4,5,11,12,17,18],"\u63d0\u4ea4":[1,8,14],"\u63d0\u4f9b":[0,1,2,3,4,7,8,9,10,11,13,14,15,16,17],"\u63d0\u4f9b\u8005":[0,1,7,8,13,14],"\u63d0\u5347":[3,10,16],"\u63d0\u53d6":[3,10],"\u63d0\u793a":[1,3,8,10,14],"\u63d0\u793a\u4fe1\u606f":[1,8,14],"\u63d0\u9192":[3,10],"\u641c\u7d22":[1,8,14],"\u64cd\u4f5c":[3,4,6,10,11,16,17],"\u652f\u6301":[1,2,3,4,5,8,9,10,11,12,14,15,16,17,18],"\u652f\u6491":[3,10,16],"\u6536\u5230":[0,7,13],"\u6545\u969c":[3,10],"\u6548\u7387":[3,10,16],"\u6570\u636e":[0,1,3,4,5,7,8,10,11,12,13,14,16,17,18],"\u6570\u636e\u5305":[0,7,13],"\u6570\u636e\u5904\u7406":[3,10],"\u6570\u636e\u5e93":[0,3,4,7,10,11,13,16,17],"\u6570\u636e\u6e90":[3,10,16],"\u6570\u745e":[2,3,5,9,10,12,15,18],"\u6570\u745e\u662f":[3,10,16],"\u6570\u76ee":6,"\u6570\u7ec4":[0,4,7,11,13,17],"\u6570\u91cf":[1,3,5,8,10,12,14,18],"\u6570\u94fe":[0,7,13],"\u6574\u4e2a":[1,8,14],"\u6574\u4f53":6,"\u6574\u578b":[4,11,17],"\u6574\u6570":[0,4,7,11,13,17],"\u6587\u4ef6":[3,5,6,10,12,18],"\u6587\u4ef6\u540d":[0,4,7,11,13,17],"\u6587\u4ef6\u540d\u79f0":[0,7,13],"\u6587\u4ef6\u5939":[0,4,7,11,13,17],"\u6587\u4ef6\u7cfb\u7edf":[3,10],"\u6587\u672c":[1,4,8,11,14,17],"\u6587\u672c\u6846":[1,8,14],"\u6587\u6863":[1,2,3,4,5,8,9,10,11,12,14,15,16,17,18],"\u65ad\u7ebf":[3,10],"\u65b0\u589e":[3,10],"\u65b0\u5efa":[0,7,13],"\u65b9\u5f0f":[0,1,3,4,5,7,8,10,11,12,13,14,16,17,18],"\u65b9\u6cd5":[1,3,4,5,8,10,11,12,14,17,18],"\u65e0\u5b9a":[3,10],"\u65e0\u6548":[1,8,14],"\u65e0\u6cd5":[3,10],"\u65e0\u8bba":[4,11],"\u65e0\u9700":[4,11,17],"\u65e5\u5fd7":[4,6,11,17],"\u65f6\u523b":[1,4,8,11,14,17],"\u65f6\u7528":[4,11,17],"\u65f6\u95f4":[1,4,8,11,14,17],"\u662f\u5426":[0,4,7,11,13,17],"\u662f\u5426\u662f":[0,7,13],"\u663e\u793a":[1,8,14],"\u666e\u901a":[5,12,18],"\u667a\u80fd":[0,3,5,6,7,10,12,13,16,18],"\u66f4\u6539":[0,3,7,10,13],"\u66f4\u65b0":[1,4,6,8,11,14,17],"\u6700\u5c0f":[2,9,15],"\u6700\u65b0":[0,2,4,7,9,11,13,15,17],"\u6700\u8fd1":[1,8,14],"\u6700\u9ad8":[2,9,15],"\u6709\u503c":[4,11,17],"\u6709\u6548":[5,12,18],"\u6709\u6743":[0,7,13],"\u670d\u52a1":[0,2,3,4,7,9,10,11,13,15,16,17],"\u670d\u52a1\u5668":[0,2,7,9,13,15],"\u670d\u52a1\u5668\u4e4b\u95f4":[0,7,13],"\u670d\u52a1\u5668\u53d1\u9001":[0,7,13],"\u670d\u52a1\u7aef":[0,3,7,10,13,16],"\u672b\u5c3e":[4,11,17],"\u672c\u5730":[1,4,8,11,14,17],"\u672c\u673a":[0,7,13],"\u673a\u5236":[3,4,10,11,17],"\u6743\u8861":[3,10,16],"\u6743\u9650":[0,2,3,4,6,7,9,10,11,13,15,17],"\u6761\u6570":[0,7,13],"\u6761\u76ee":[4,11,17],"\u6765\u6e90":[4,11,17],"\u6765\u81ea":[3,10],"\u6784\u4ef6":[3,10,16],"\u6784\u5efa":[5,12,18],"\u679a\u4e3e":[4,11],"\u67d0\u4e00":[0,7,13],"\u67d0\u4e2a":[0,1,7,8,13,14],"\u67d0\u5b50":[0,7,13],"\u67d0\u9879":[1,8,14],"\u67e5\u770b":[1,2,3,4,5,6,8,9,10,11,12,14,15,17,18],"\u67e5\u8be2":[4,6,11,17],"\u6807\u503c":[0,7,13],"\u6807\u7b7e":[3,10],"\u6807\u8bc6":[1,4,8,11,14,17],"\u6821\u9a8c":[1,3,8,10,14],"\u6837\u5f0f":[3,10,16],"\u6839\u636e":[4,5,11,12,17,18],"\u6839\u76ee\u5f55":[5,12,18],"\u683c\u5f0f":[0,2,4,7,9,11,13,15,17],"\u6846\u4e2d":[1,8,14],"\u6846\u5185":[1,8,14],"\u6846\u67b6":[3,6,10,16],"\u6982\u89c8":6,"\u6982\u8ff0":6,"\u6a21\u5757":[1,2,5,8,9,12,14,15,18],"\u6a21\u5f0f":[0,1,2,3,7,8,9,10,13,14,15,16],"\u6a21\u62df":[4,11,17],"\u6a21\u677f":[3,4,6,10,11,17],"\u6b21\u6570":[1,8,14],"\u6b63\u5219":17,"\u6b63\u5219\u8868\u8fbe\u5f0f":17,"\u6b63\u5e38":[1,8,14],"\u6b63\u786e":[3,10,16],"\u6b63\u786e\u6027":[3,10,16],"\u6b64\u65f6":[0,1,2,4,7,8,9,11,13,14,15,17],"\u6b65\u9aa4":[2,9,15],"\u6bcf\u4e2a":[4,5,11,12,17,18],"\u6bcf\u65e5":6,"\u6bd4\u5982":[4,11,17],"\u6ca1\u6709":[0,1,4,7,8,11,13,14,17],"\u6cd5\u5206\u6790":[3,10,16],"\u6ce8\u518c":[4,11,17],"\u6ce8\u610f":[4,11,17],"\u6ce8\u89e3":[3,4,6,10,11,17],"\u6ce8\u91ca":6,"\u6d41\u7a0b":[0,3,6,7,10,13],"\u6d41\u91cf":[1,8,14],"\u6d4b\u8bd5":[0,2,3,4,7,9,10,11,13,15,17],"\u6d4b\u8bd5\u7528\u4f8b":[0,7,13],"\u6d4f\u89c8":[2,9,15],"\u6d4f\u89c8\u5668":[2,9,15],"\u6d88\u606f":[3,10],"\u6d88\u8017":[5,12,18],"\u6d89\u53ca":[2,9,15],"\u6dfb\u52a0":[4,11,17],"\u6e32\u67d3":[3,5,10,12,18],"\u6e90\u6587\u4ef6":[5,12,18],"\u6f0f\u6d1e":[3,10],"\u70b9\u51fb":[1,2,8,9,14,15],"\u70b9\u5bf9\u70b9":[3,10],"\u7136\u540e":[1,5,8,12,14,18],"\u7248\u672c":[0,2,3,7,9,10,13,15],"\u7279\u70b9":6,"\u72b6\u6001":[3,6,10,16],"\u73af\u5883":6,"\u7406\u4e8b":[5,12,18],"\u751f\u6210":[1,3,4,6,8,10,11,14,16,17],"\u7528\u4e8e":[1,2,3,4,5,8,9,10,11,12,14,15,16,17,18],"\u7528\u4f5c":[2,9,15],"\u7528\u5230":[4,11,17],"\u7528\u6237":[2,4,6,9,11,15,17],"\u7528\u6237\u540d":[0,4,7,11,13,17],"\u7528\u6237\u6570":[1,8,14],"\u7528\u6237\u6570\u91cf":[1,8,14],"\u7528\u8005":[0,1,7,8,13,14],"\u7533\u8bf7":6,"\u754c\u9762":[0,3,6,7,10,13],"\u767b\u5f55":[1,6,8,14],"\u767b\u9646":[1,8,14],"\u76d1\u542c":[2,9,15],"\u76d1\u6d4b":[3,10,16],"\u76ee\u524d":[1,8,14],"\u76ee\u5f55":[1,2,3,4,5,6,8,9,10,11,12,14,15,17,18],"\u76ee\u6807":[0,4,7,11,13,17],"\u76ee\u6807\u503c":[0,7,13],"\u76ee\u7684":[3,10,16],"\u76f4\u63a5":[0,4,5,7,11,12,13,17,18],"\u76f8\u5173":[1,3,4,8,10,11,14,17],"\u76f8\u5e94":[1,8,14],"\u770b\u5230":[1,8,14],"\u770b\u89c1":[1,8,14],"\u7740\u91cd":[3,10,16],"\u786c\u76d8":[3,10],"\u786e\u5b9a":[1,8,14],"\u793a\u4f8b":[1,2,3,6,8,9,10,14,15],"\u793a\u610f":0,"\u793a\u610f\u56fe":0,"\u79bb\u7ebf":[1,2,8,9,14,15],"\u79c1\u6709":[1,8,14],"\u79c1\u94a5":[0,7,13],"\u79f0\u4e3a":[0,7,13],"\u79fb\u9664":[1,8,14],"\u7a33\u5b9a":[3,10],"\u7a33\u5b9a\u6027":[3,10],"\u7aef\u53e3":[0,1,2,4,7,8,9,11,13,14,15,17],"\u7aef\u53e3\u53f7":[0,4,7,11,13,17],"\u7b26\u53f7":[5,12,18],"\u7b2c\u4e00":[0,2,4,5,7,9,11,12,13,15,17,18],"\u7b2c\u4e00\u4e2a":[4,5,11,12,17,18],"\u7b2c\u4e00\u6b21":[0,7,13],"\u7b2c\u4e00\u7ec4":[2,9,15],"\u7b2c\u4e09":[5,12,18],"\u7b2c\u4e09\u4e2a":[5,12,18],"\u7b2c\u4e8c":[2,4,5,9,11,12,15,17,18],"\u7b2c\u4e8c\u4e2a":[4,5,11,12,17,18],"\u7b2c\u4e8c\u7ec4":[2,9,15],"\u7b2c\u51e0":[0,7,13],"\u7b2c\u51e0\u4e2a":[0,7,13],"\u7b49\u4ef7":[4,11,17],"\u7b56\u7565":[0,3,7,10,13],"\u7b7e\u540d":[0,3,4,7,10,11,13,17],"\u7b80\u4ecb":[4,11,17],"\u7b80\u5355":[3,10],"\u7b97\u6cd5":[3,5,10,12,18],"\u7ba1\u7406":[2,3,6,9,10,15,16],"\u7ba1\u7406\u5458":[0,1,7,8,13,14],"\u7ba1\u7406\u8005":[0,1,7,8,13,14],"\u7be1\u6539":[2,9,15],"\u7c7b\u4e2d":[0,7,13],"\u7c7b\u4f3c":[0,5,7,12,13,18],"\u7c7b\u578b":[3,4,5,6,10,11,12,16,17,18],"\u7c92\u5ea6":[3,10,16],"\u7cfb\u5217":[0,7,13],"\u7cfb\u7edf":[1,3,8,10,14],"\u7ea6\u5b9a":[1,6,8,14],"\u7ebf\u56fe":[1,8,14],"\u7ebf\u7a0b":[3,6,10],"\u7ec4\u6210":[0,2,7,9,13,15],"\u7ec4\u7f51":[1,2,3,8,9,10,14,15],"\u7ec6\u7c92":[3,10,16],"\u7ec6\u7c92\u5ea6":[3,10,16],"\u7ec8\u6b62":[1,8,14],"\u7ed1\u5b9a":[4,11,17],"\u7ed3\u6784":6,"\u7ed3\u679c":[3,4,5,10,11,12,17,18],"\u7ed3\u679c\u663e\u793a":[1,8,14],"\u7edf\u8ba1":[3,6,10,16],"\u7edf\u8ba1\u56fe":[3,10,16],"\u7edf\u8ba1\u56fe\u8868":[3,10,16],"\u7ef4\u62a4":[1,8,14],"\u7f13\u5b58":[2,9,15],"\u7f16\u5199":[0,7,13],"\u7f16\u7801":[0,4,7,11,13,17],"\u7f16\u7a0b":[5,12,18],"\u7f16\u7a0b\u8bed\u8a00":[5,12,18],"\u7f16\u8bd1":[3,5,10,12,16,18],"\u7f16\u8bd1\u5668":[3,10,16],"\u7f16\u8f91":[0,3,6,7,10,13,16],"\u7f16\u8f91\u5668":6,"\u7f16\u8f91\u6846":[3,10,16],"\u7f51\u7edc":[1,3,6,8,10,14],"\u7f51\u7edc\u62d3\u6251":6,"\u8054\u52a8":[3,10],"\u80a9\u8180":[3,10,16],"\u811a\u672c":[2,3,9,10,15,16],"\u81ea\u52a8":[2,3,4,5,9,10,11,12,15,17,18],"\u81ea\u5b9a":[1,3,4,5,8,10,11,12,14,17,18],"\u81ea\u5b9a\u4e49":[1,3,4,5,8,10,11,12,14,17,18],"\u81ea\u5df1":[1,8,14],"\u81ea\u5e26":[4,5,11,12,17,18],"\u81ea\u884c":[0,4,7,11,13,17],"\u81f3\u591a":[3,4,10,11],"\u81f3\u5c11":[3,4,10,11],"\u8282\u70b9":[3,6,10],"\u82e5\u52a0\u6b64":[4,11,17],"\u82e5\u8be5":[1,8,14],"\u82f1\u6587":[4,11],"\u8303\u56f4":[1,5,8,12,14,18],"\u83b7\u53d6":[1,3,4,5,8,10,11,12,14,17,18],"\u83b7\u5f97":[0,4,7,11,13,17],"\u83dc\u5355":[2,6,9,15],"\u8425\u4e1a":[0,7,13],"\u8425\u4e1a\u989d":[0,7,13],"\u865a\u62df":[2,9,15],"\u865a\u62df\u673a":[2,9,15],"\u867d\u7136":[5,12,18],"\u884c\u4f7f":[1,8,14],"\u8868\u540d":[0,7,13],"\u8868\u662f":[1,8,14],"\u8868\u683c":[1,3,8,10,14,16],"\u8868\u76d8":6,"\u8868\u793a":[0,4,5,7,11,12,13,17,18],"\u8868\u8fbe":[3,10,16,17],"\u8868\u8fbe\u5f0f":17,"\u8868\u9879":[1,8,14],"\u89c4\u6a21":[2,9,15],"\u89c6\u56fe":6,"\u89d2\u8272":[1,3,6,8,10,14],"\u89e3\u538b":[2,9,15],"\u89e3\u5bc6":6,"\u89e3\u6790":[4,11,17],"\u8ba1\u7b97":[0,2,3,7,9,10,13,15,16],"\u8ba1\u8d39":[3,10],"\u8ba1\u91cf":[3,10],"\u8ba2\u9605":[1,3,5,6,8,10,12,14,18],"\u8ba4\u8bc1":[1,2,8,9,14,15],"\u8bb0\u5f55":[3,4,10,11,17],"\u8bb8\u53ef":[1,8,14],"\u8bb8\u591a":[3,10,16],"\u8bbe\u7f6e":[0,4,6,7,11,13,17],"\u8bbf\u95ee":[0,3,5,6,7,10,12,13,16,18],"\u8bbf\u95ee\u63a7\u5236":[0,3,7,10,13,16],"\u8bc1\u4e66":6,"\u8bc6\u522b":[5,12,18],"\u8bcd\u6cd5":[3,10,16],"\u8bd5\u7528":[0,7,13],"\u8be5\u56fe":[1,8,14],"\u8be5\u6b21":[1,8,14],"\u8be5\u9879":[3,10,16],"\u8be6\u7ec6":[1,4,5,8,11,12,14,17,18],"\u8be6\u7ec6\u4fe1\u606f":[1,8,14],"\u8bed\u4e49":[3,6,10],"\u8bed\u53e5":[4,5,11,12,17,18],"\u8bed\u6cd5":[3,6,10,16],"\u8bed\u6cd5\u5206\u6790":[3,10,16],"\u8bed\u8a00":[3,5,10,12,16,18],"\u8bf4\u660e":[0,1,6,7,8,13,14,17],"\u8bf7\u6c42":[2,4,5,9,11,12,15,17,18],"\u8bf7\u6c42\u8005":[5,12,18],"\u8c03\u5ea6":[3,10,16],"\u8c03\u7528":[3,4,5,6,10,11,12,16,17,18],"\u8c03\u7528\u51fd\u6570":[4,11,17],"\u8c03\u7528\u8005":[0,7,13],"\u8c03\u8bd5":[0,2,7,9,13,15],"\u8d1f\u8d23":[1,8,14],"\u8d1f\u8d23\u7ba1\u7406":[1,8,14],"\u8d26\u53f7":6,"\u8d26\u672c":[2,3,4,9,10,11,15,17],"\u8d44\u6e90":[0,3,5,6,7,10,12,13,16,18],"\u8d77\u59cb":[0,7,13],"\u8def\u5f84":[1,4,6,8,11,14,17],"\u8def\u7531":[3,6,10],"\u8df3\u8f6c":[3,10],"\u8eab\u4efd":[0,2,7,9,13,15],"\u8eab\u4efd\u9a8c\u8bc1":[0,7,13],"\u8f93\u5165":[1,2,4,8,9,11,14,15,17],"\u8f93\u5165\u6846":[1,8,14],"\u8fbe\u5f0f":17,"\u8fc7\u671f":[1,8,14],"\u8fc7\u7a0b":[5,12,18],"\u8fd0\u884c":[0,1,2,5,7,8,9,12,13,14,15,18],"\u8fd4\u56de":[3,4,5,10,11,12,17,18],"\u8fd4\u56de\u503c":[4,11,17],"\u8fd8\u4f1a":[1,8,14],"\u8fd8\u662f":[0,1,7,8,13,14],"\u8fd9\u4e2a":[1,8,14],"\u8fd9\u4e9b":[3,10,16],"\u8fd9\u662f":[5,12,18],"\u8fd9\u91cc":[4,11,17],"\u8fdb\u7a0b":[1,3,8,10,14],"\u8fdb\u884c":[0,1,2,3,4,7,8,9,10,11,13,14,15,17],"\u8fde\u63a5":[1,3,4,6,8,10,11,14,17],"\u9002\u5e94":[3,10],"\u9009\u4e2d":[1,8,14],"\u9009\u53d6":[1,8,14],"\u9009\u5b57":[0,7,13],"\u9009\u5b9a":[1,8,14],"\u9009\u62e9":[1,2,8,9,14,15],"\u9009\u9879":[0,7,13],"\u9017\u53f7":[0,7,13],"\u901a\u4fe1":[1,8,14],"\u901a\u5e38":[5,12,18],"\u901a\u8baf":[3,10,16],"\u901a\u8fc7":[0,1,3,4,5,6,7,8,10,11,12,13,14,16,17,18],"\u903b\u8f91":[2,3,9,10,15,16],"\u904d\u5386":[4,11,17],"\u90a3\u4e48":[1,8,14],"\u90e8\u5206":[0,3,4,7,10,11,13,17],"\u90e8\u7f72":[2,4,9,11,15,17],"\u914d\u5408":[4,11,17],"\u914d\u7f6e":[2,3,4,6,9,10,11,15,17],"\u914d\u7f6e\u6587\u4ef6":[3,10],"\u91cc\u9762":[4,11,17],"\u91cd\u590d":[3,10],"\u91cd\u65b0":[1,8,14],"\u91cd\u8f7d":[1,8,14],"\u91cd\u8fde\u540e":[3,10],"\u91cf\u503c":[5,12,18],"\u94a5\u4e3a":[2,9,15],"\u94a5\u5bf9":[0,7,13],"\u94fe\u63a5":[0,2,7,9,13,15],"\u9519\u8bef":[3,10],"\u955c\u50cf":[0,7,13],"\u95ee\u9898":[3,10],"\u95f4\u9694":[0,7,13],"\u9644\u52a0":[0,7,13],"\u9664\u4e86":[5,12,18],"\u968f\u5373":[1,8,14],"\u968f\u673a":[3,10,16],"\u9694\u5f00":[0,4,7,11,13,17],"\u9694\u79bb":[3,10],"\u96c6\u5408":[0,7,13],"\u96c6\u7fa4":[3,6,10],"\u9700\u5148":[0,7,13],"\u9700\u7528":[5,12,18],"\u9700\u7531":[0,7,13],"\u9700\u8981":[0,1,4,5,7,8,11,12,13,14,17,18],"\u9759\u6001":[3,10,16],"\u9762\u5411":[3,10,16],"\u9875\u9762":[1,3,8,10,14],"\u9879\u76ee":[2,4,6,9,11,15],"\u9879\u76ee\u540d\u79f0":[0,7,13],"\u9996\u5148":[5,12,18],"\u9a8c\u7b7e":[4,11,17],"\u9a8c\u8bc1":[0,4,7,11,13,17],"\u9ed8\u8ba4":[0,1,2,4,7,8,9,11,13,14,15,17],"boolean":[4,11,17],"byte":[13,19],"case":[13,19],"class":[5,12,18],"contract%":[0,7,13],"default":[4,11,13,17,19],"do":[4,11,17],"enum":[13,19],"export":[1,4,5,8,11,12,14,17,18],"for":[4,5,11,12,13,17,18,19],"function":[0,4,5,7,11,12,13,17,18],"if":[4,11,13,17,19],"import":6,"in":[0,5,6,7,12,13,18,19],"int":[5,12,18],"java1.8":[2,9,15],"length%":[0,7,13],"long":[0,4,7,11,13,17],"lskr%":[13,19],"new":[0,5,7,12,13,18,19],"null":[0,4,7,11,13,17],"public":[2,3,5,9,10,12,15,18],"return":[0,4,5,7,11,12,13,17,18],"static":[0,5,7,12,13,18],"true":[0,4,5,7,11,12,13,17,18,19],"v0.1":[3,10],"v0.2":[3,10],"v0.3":[3,10],"v0.35":[3,10],"v0.4":[3,10],"v0.45":[3,10],"v0.5":[3,10],"v0.6":[3,10],"v0.7":[3,10],"v0.78":[3,10],"v0.8":[3,10],"v0.90":[3,10],"v0.95":[3,10],"v0.97":[3,10],"v0.99":[3,10],"v1.0":[3,10],"v1.1":[3,10],"v1.2":[3,10],"v1.3":[3,10],"v1.4":[3,10],"var":[0,4,5,7,11,12,13,17,18],"vqbea5ee0y5hqeileoquymhbose%":[13,19],"with":[3,10,13,16,19],"yjs%":[0,7,13],_1583410158761:[0,7,13],a88bf4eb:[13,19],aa:[0,7,13],aa_1572335939893:[0,7,13],aaaaaaaaaaaaaaaaaaaaaaaaaaa:[13,19],abc:[0,4,5,7,11,12,13,17,18],abcev:[5,12,18],accept:[0,4,7,11,13,17],access:[5,6,12,18],accesspolici:[0,7,13],actempl:[3,10],action:[0,4,5,7,11,12,13,17,18],activ:[0,7,13],add:[0,7,13],addnod:[0,7,13],address:[4,11,17],adf:[4,11,17],adfa:[4,11,17],agentwebcont:[2,9,15],algorigthm:[0,7,13],algorithm:[0,7,13],all:[13,19],aload:[0,7,13],alreadi:[0,7,13],analysisbyindustri:[0,7,13],analysisexecuteresult:1,and:[13,19],annot:6,annotationsampl:[0,7,13],anonym:[0,1,7,8,13,14],antlr:[3,10,16],apach:[3,10,16],apachev2:[3,10,16],api:[5,6,12,13,18,19],apinam:[0,7,13],appdataanalysi:[0,7,13],appdatasourc:[0,7,13],applic:[4,11,17],applylistcount:[0,7,13],applynoderol:[0,7,13],applyrol:[0,7,13],apt:[2,9,15],areturn:[0,7,13],arg0:[4,11,17],arg1:[4,11,17],arg2:[4,11,17],arg3:[4,11,17],arg:[0,4,5,7,11,12,13,17,18],argg:[5,12,18],argument:[0,7,13],as:[13,19],asciimath:[13,19],asm:[3,10,16],asp:[4,11,17],astor:[0,7,13],async:[4,11,17],asyncexampl:[4,11,17],asyncutil:6,at:[4,11],at_least_onc:4,at_most_onc:[4,11],attribut:[3,10,16],aug:[0,7,13],authnodemanag:[0,7,13],authnoderol:[0,7,13],authorizedus:[0,7,13],b0:[0,7,13],b10:[0,7,13],b11:[0,7,13],b12:[0,7,13],b13:[0,7,13],b1:[0,7,13],b2:[0,7,13],b3:[0,7,13],b4:[0,7,13],b4f06d:[0,7,13],b5:[0,7,13],b60e8dd61c5d32be8058bb8eb970870f07233155:[4,11,17],b6:[0,7,13],b7:[0,7,13],b8:[0,7,13],b9:[0,7,13],baa:[4,11,17],baidu:[0,4,7,11,13,17],base64:[0,7,13,19],base64encodeddata:[0,7,13],bash:6,basicinfo:[0,7,13],bb:[4,11,17],bdcluster:[2,9,15],bdcoin:[0,7,13],bdcontract:[4,6,11,13,15,16,17],bdledger:[0,3,4,7,10,11,13,17,19],bdserver:[2,3,9,10,15],bdw:[0,7,13],bdwaa:[0,7,13],bdware:[0,7,16,19],bdwarecli:[3,10],bdwareconfigtool:[0,2,7,9,13,15],bdwarecontract:[3,10],bdwarehttp:[0,7,13],bdwarejavacli:[2,9,15],bdwareledg:[3,10,16],bdwareprojectdir:[2,9,15],bdwaretimedbexampl:[4,11,17],bdwaretimeseriesdb:[4,11,17],bdwaretimeseriesdbutil:6,bdwarewebcli:[2,5,9,12,15,18],be:[13,19],belong:[13,19],biddingexampl:[0,7,13],block:[0,7,13,19],blockhash:[13,19],blocktimestamp:[13,19],bmftzswgc2nvcmuscmphy2ssidkwlapsdwn5lca5mqo:[0,7,13],bodi:[13,19],bool:[0,5,7,12,13,18],bootstrap:[0,3,7,10,13,16],bqyrl:[4,11,17],branch:[4,5,11,12,17,18],brian:[4,11,17],bsd:[3,10,16],bug:[3,10],build:[5,6,12,18],builder:[5,12,18],button:[5,12,18],by:[13,19],caihq:[5,12,18],call:[0,7,13],callsit:[0,7,13],categori:[0,7,13],cd:[2,9,15],centermanag:[0,2,7,9,13,15],centernodelist:1,centernodepag:1,centernodepreview:1,centernodeunit:1,centernodeunitcr:1,centerport:[0,2,3,7,9,10,13,15],centerportalw:[0,7,13],cento:[2,9,15],centos7:[3,10],certpassword:[0,7,13],certpath:[0,7,13],cfhbfhpfdw:[13,19],cfirst:[4,11],changebdledg:[0,7,13],changedoipconfig:[0,7,13],changedumpperiod:[0,7,13],changeipport:[0,7,13],changencfil:[0,7,13],changenodecent:[0,7,13],changenodenam:[0,7,13],changeothernc:[0,7,13],changepubl:[0,7,13],changeyjspath:[0,7,13],chmod:[2,9,15],chooseinst:1,cid:[0,7,13],cimanag:[0,7,13],citi:[4,11],cj:[4,11],ckokgxrga:[4,11,17],clast:[4,11],client:[2,4,9,11,15,17],close:[4,11,17],cluster:[1,2,8,9,14,15],clusterconnect:[0,7,13],clusterwebcont:[2,9,15],cmaction:[0,7,13],cmmanag:[0,7,13],cmstart:[2,9,15],cn:[2,9,15],cname:[4,11],code:[0,7,13],codemanage1:1,codemanage2:1,codemanage3:1,codemanage4:1,codemanage5:1,codemanage6:1,codemanage7:1,codemanagemenu:1,codemirror:[3,10,16],collect:[4,11,17],com:[0,4,7,11,13,17],compil:[0,7,13],config:[13,19],config_vers:[13,19],conn:[4,11,17],connect:[4,11,17],connector:[4,11],connectto:[0,7,13],consol:[0,7,13],contain:[4,11,17],content:[0,4,5,7,11,12,13,17,18],continu:[0,7,13],contract:[0,3,4,6,7,10,11,13,17],contractapi:[2,9,15],contractcontrol:[0,7,13],contractengine021:[0,7,13],contractexampl:[0,7,13],contractexecutor:[0,7,13],contracthandl:[0,7,13],contractid:[0,4,7,11,13,17],contractinstancemanag:[0,7,13],contractmanag:[0,7,13],contractmod:1,contractnam:[0,7,13],contractprovid:[0,7,13],contractstatu:[0,7,13],contractus:[0,7,13],control:[0,7,13],costtim:[0,7,13],count:[0,4,7,11,13,17,19],countactionlogbycategori:[0,7,13],countcmlogbycategori:[0,7,13],countcontractloggroupbyact:[0,7,13],countcontractloggroupbycategori:[0,7,13],counter:[0,7,13],counti:[4,11],countloggroupbycategori:[0,7,13],countnodeloggroupbycategori:[0,7,13],countrol:[0,7,13],cp:[0,2,7,9,13,15],cpu:[3,10],cpuid:[3,10],cr:[4,11,17],creat:[13,19],createfil:[0,7,13],createledg:[0,7],createstat:[4,11,17],createtrustunit:[0,7,13],createwssocket:[0,7,13],creator:[13,19],crypto:[3,10,16],css:[5,12,18],cst:[0,7,13],csvfromtempl:[0,7,13],current:[13,19],currenttimemilli:[4,11,17],cword:[4,11],d3a92e1184bbc5817ebda5c2ad498e4ff1d240009b4f06d:[0,7,13],dac:[0,3,7,10,13],dad:[5,12,18],data:[0,4,5,7,11,12,13,17,18,19],datachain:[0,7,13],datat:[3,10,16],datatim:[4,11,17],datawar:[4,11,17],date:[0,4,7,11,13,17],db:[4,11,17],dbdir:[4,11,17],dbname:[4,11,17],dbpwd:[0,7,13],dburl:[0,7,13],dbusernam:[0,7,13],dbutil:[4,11,17],dd867469f5adf9986e4ea6215febeae50c7d4c3836d002cf8c17050dfca031fd2595ffa8646e9eeae53150d2cbaea690e27d818eaf5cea3632ee1b69c3307a4b631e97346086e2d48fac2ba7f5b75ccbd19ebf495c0e6f9934d69e3b083da4d42e46c991e0c2ea8bb45d59f31f46d0ec700fb01f2fdd275:[0,7,13],deb:[2,9,15],debug:[1,4,8,11,14,17],def:[4,11,17],defaultaccept:[0,7,13],defaultt:[4,11,17],delet:[0,7,13],deletefil:[0,7,13],deleteinfo:[0,7,13],deleteit:[4,11,17],deletekei:[4,11,17],deletememoryfil:[0,7,13],deleterol:[0,7,13],deletetrustunit:[0,7,13],deploytopolog:2,descript:[1,6,8,14],dest:[4,11,17],destin:[4,11,17],dev:[13,19],digitalobject:[4,11,17],dir:[0,4,7,11,13,17],distributecontract:[0,7,13],div:[5,12,18],djxc:[13,19],dmkkwvzxxvm:[13,19],dobodi:[4,11,17],doc:[0,4,7,11,13,17],docker:[3,10],doid:[4,11,17],doip:[0,4,7,11,13,17],doipconfig:[0,3,7,10,13],doipexampl:[4,11,17],doiputil:6,dom:[3,10,16],domin:[4,11],don:[13,19],done:[4,5,11,12,17,18],dorepo:[3,10],dosignatur:[0,7,13],dou:[0,7,13],downloadcontract:[0,7,13],downloadcontractfromotherhost:[0,7,13],downloaduuid:[0,7,13],dpkg:[2,9,15],driver:[4,11,17],driverclass:[4,11],dump:[3,10],dumpcontract:[0,7,13],dup:[0,7,13],dyj:[0,7,13],dyn:[0,7,13],earlier:[13,19],easi:[4,11,17],echart:[3,10,16],ecma5:6,ecmascript6:[4,11,17],edg:[0,7,13],elemeprovid:[4,11,17],els:[4,11,17],email:[4,11,17],empty22:[0,7,13],encod:[13,19],encodeuricompon:[13,19],end:[0,7,13,19],end_timestamp:[13,19],endtimestamp:[13,19],error:[4,11,17],es6:[5,12,18],evalu:[0,7,13],event:[4,5,11,12,17,18],eventpub:[0,5,7,12,13,18],eventpuberat3966:[0,7,13],eventrel:[0,7,13],eventsub:[0,5,7,12,13,18],eventsuberatchq:[0,7,13],exampl:[4,11,17],executecontract:[0,1,6,7,8,13,14],executecontractp2ptrustfulli:[0,7,13],executecontracttrustfulli:[0,7,13],executecurrentcontract:[4,5,11,12,18],executequeri:[4,11,17],executeresult:1,executetim:[0,7,13],executionga:[0,7,13],exit:[0,7,13],expiretim:[0,7,13],extraga:[0,7,13],fail:[0,4,7,11,13,17],fals:[0,4,7,11,13,17],fieldlist:[0,7,13],file:[0,3,4,7,10,11,13,17],filecont:[0,7,13],filelist:[0,7,13],filenam:[0,5,7,12,13,18],filesampl:[4,11,17],fileutil:6,find:[4,11,17],first:[4,11],flow:[0,7,13],flx5pmy8m1qsagzdkt1rwbkdemo:[13,19],follow:[13,19],forkcontract:[0,7,13],formdesc:[0,7,13],from:[0,4,5,7,11,12,13,17,18,19],fromcontract:[5,12,18],full:[13,19],fun2:[5,12,18],fun:[5,12,18],function_nam:[0,7,13],fuunw:[4,11,17],gas:[3,10],gasexampl:[3,10],generateannotationsampl:[0,7,13],generateappdataanalysi:[0,7,13],generateappdatasourc:[0,7,13],generatebdcoineventproject:[0,7,13],generatebdcoinproject:[0,7,13],generatebiddingexampl:[0,7,13],generatecontractexecutor:[0,7,13],generatecsvproject:[0,7,13],generatedac4bdoa:[0,7,13],generatedac4bdoa_persist:[0,7,13],generatedacsampl:[0,7,13],generatedlib:[0,7,13],generateemptyproject:[0,7,13],generateeventpublish:[0,7,13],generateeventsubscrib:[0,7,13],generategasexampl:[0,7,13],generategeneratetfmac:[0,7,13],generatehello:[0,7,13],generatehttpexampl:[0,7,13],generateincent:[0,7,13],generatejsonexampl:[0,7,13],generateledgerexampl:[0,7,13],generateledgerproject:[0,7,13],generatelicencemanag:[0,7,13],generateloggerexampl:[0,7,13],generatemysqlexampl:[0,7,13],generatemysqlproject:[0,7,13],generatepostgresqlsampl:[0,7,13],generatereadm:[0,7,13],generaterendersampl:[0,7,13],generaterocksdbsampl:[0,7,13],generatesm2exampl:[0,7,13],generatestaticresourc:[0,7,13],generatetflinux:[0,7,13],genesi:[13,19],get:[0,2,7,9,13,15,19],getacceptlist:[0,7,13],getapplylist:[0,7,13],getcodebyid:[0,7,13],getcollect:[4,11,17],getcolumncount:[4,11,17],getcolumnnam:[4,11,17],getconn:[4,11,17],getconncount:[0,7,13],getcontrolflowbyfilenam:[0,7,13],getcount:[4,11,17],getdatabas:[4,11,17],getdumpperiod:[0,7,13],getelem:[0,7,13],getencodeduuid:[0,7,13],getgasvalu:[0,7,13],gethashabstractloc:[0,7,13],gethashloc:[0,7,13],getlastlog:[0,7,13],getlog:[0,7,13],getlogs:[0,7,13],getlong:[4,11,17],getmainfram:[0,4,5,7,11,12,13,18],getmanagerpubkei:[0,7,13],getmetadata:[4,11,17],getmethod:[0,7,13],getmongodbcli:[4,11,17],getncfil:[0,7,13],getnext:[4,11,17],getnodeid:[0,7,13],getnoderol:[0,7,13],getnoderoledeprec:[0,7,13],getnodesessionid:[0,7,13],getnodetrustunit:[0,7,13],getothernc:[0,7,13],getpeerid:[0,7,13],getprogress:[4,11,17],getproject:[0,7,13],getprop:[0,7,13],getrol:[0,7,13],getscop:[0,7,13],getsessionid:[0,7,13],getstat:[0,7,13],getstr:[4,11,17],gettemplatelist:[0,7,13],gettim:[0,7,13],github:[4,11,17],global:[0,5,6,7,12,13,18],googl:[13,19],gplv2:[3,10,16],gqnr:[4,11,17],grpc:[3,10,16],grpcpool:[3,10],guassdb200:[4,11],gw1:[4,11,17],handl:[0,7,13],handler:[0,4,5,7,11,12,13,17,18],hangup:[3,10],has:[0,7,13,19],hasclass:[0,7,13],hash:[4,11,17,19],hasnext:[4,11,17],header:[4,11,17],hello:[0,5,7,12,13,18],hello_2020:[0,7,13],helloworld:[5,12,18],hgiesugi:[4,11,17],hhh:[0,7,13],hhhhh:[0,7,13],htce:[4,11,17],html:[0,1,2,3,4,5,7,8,9,10,11,12,13,14,15,17,18],http:[1,2,3,4,6,8,9,10,11,14,15,16,17,19],httpexampl:[4,11,17],httpget:[4,11,17],httppermiss:[4,11,17],httputil:6,id:[1,4,5,8,11,12,14,17,18],ide:[0,7,13],identifi:[13,19],importcontractinstancecodebydoi:[0,7,13],incent:[3,10],includ:[13,19],include_transact:[13,19],includetransact:[13,19],index:[13,19],indextyp:[0,7,13],info:[4,11,17],init:[0,4,5,7,11,12,13,17,18],innerhtml:[5,12,18],input:[0,7,13],inputstr:[4,11,17],insid:[13,19],insnlimit:[5,12,18],instal:[2,3,9,10,15],instancemanag:[0,7,13],intanceexecut:1,integ:[4,11,17],intern:[0,7,13],internetapi:[2,9,15],interv:[0,7,13],invok:[0,7,13],invokedynam:[0,7,13],invokejava:[5,12,18],invokestat:[0,7,13],invokevirtu:[0,7,13],io:[0,1,3,6,7,8,10,13,14],iot:[3,10,16],ip:[0,2,4,7,9,11,13,15,17,19],ipport:[0,7,13],is:[5,12,13,18,19],isaccept:[0,7,13],isappend:[0,4,7,11,13,17],isinsnlimit:[0,7,13],isopen:[0,7,13],isown:[0,7,13],isparti:[0,7,13],ispriv:[0,7,13],issend:[0,7,13],it:[13,19],iter:[4,11,17],its:[13,19],jackson:[4,11,17],jar:[0,2,3,4,5,7,9,10,11,12,13,15,18],java1:[2,9,15],java:[0,2,3,4,6,7,9,10,11,13,15,16,17],java_sourc:0,javadoc:[4,11,17],javas:[4,11,17],javascript:[0,2,3,5,7,9,10,12,13,15,16,18],jdbc:[0,4,7,11,13,17],jdk:[0,2,7,9,13,15],jeffrei:[4,11,17],jpeg:[0,7,13],jqueri:[3,10,16],jqueryui:[3,10,16],jre:[2,9,15],js:[0,3,4,5,7,10,11,12,13,16,17,18],js_date:[4,11,17],js_error:[4,11,17],js_json:[4,11,17],js_math:[4,11,17],js_number:[4,11,17],js_regexp:[4,11,17],js_string:[4,11,17],json:[0,4,6,7,11,13,17],jsoncontract:[0,7,13],jsontest:[0,7,13],judg:[5,12,18],k079ax:[13,19],kb:[0,7,13],kei:[4,11,17],keypair:[4,11,17],keystor:[0,7,13],kill:[0,7,13],killallcontract:[0,7,13],killcontractprocess:[0,7,13],kv:[0,4,7,11,13,17],label:[0,7,13],lang:[0,4,7,11,13,17],last:[4,11],lastclickedprojectid:[0,7,13],later:[13,19],latex:4,lbpxocydrh:[4,11,17],ldc:[0,7,13],least:[4,11],ledger:[4,11,17],ledgercli:[4,11,17],ledgerexampl:[4,11,17],ledgerutil:6,len:[4,11,17],length:[0,5,7,12,13,18],ler:0,lhs:[4,11,17],lhsproxyaddress:[0,7,13],lib:[5,12,18],licenc:[3,10,16],licencemanag:[0,7,13],licenceservic:[0,7,13],licens:[3,10,16],line:[4,11,17],link:[5,12,18],linker:[0,7,13],linux:[2,9,15],list:[4,11,17],listadapt:[0,7,13],listallauthrol:[0,7,13],listallcontractprocess:[0,7,13],listallus:[0,7,13],listapplylist:[0,7,13],listcompiledfil:[0,7,13],listcontract:[0,7,13],listcontractprocess:[0,7,13],listen:[0,7,13],listfil:[0,7,13],listleakcontractprocess:[0,7,13],listlic:[0,7,13],listlocalcontractlog:[0,7,13],listlocalnodelog:[0,7,13],listmemoryfil:[0,7,13],listmultipointcontractprocess:[0,7,13],listnod:[0,7,13],listnodeinfo:[0,7,13],listproject:[0,7,13],listprojectpermiss:[0,7,13],listthecontractprocess:[0,7,13],listtrustunit:[0,7,13],listunauthrol:[0,7,13],lite:[2,9,15],ljava:[0,7,13],loadasstr:[5,12,18],loadconfig:[0,7,13],loadcss:[4,11],loadmemori:[0,7,13],loadnodeconfig:[0,7,13],loadresourc:[0,5,7,12,13,18],loadscript:[4,11],local:[0,4,7,11,13,17],localhost:[0,7,13],localinstal:[2,9,15],localtcprepo:[4,11,17],lockedit:[0,7,13],log1:1,log2:1,log3:1,log:[0,7,13],login:[0,7,13],loginparam:[0,7,13],logloc:[5,6,12,18],logmenu:1,logtyp:[0,5,6,7,12,13,18],longstr:[0,7,13],longtimetask:[4,11,17],lookup:[0,7,13],lopez:[4,11,17],loushuai:[0,7,13],lqitwzks5hlun6v:[13,19],lskr:[13,19],luxttcm:[13,19],lwrp:[0,7,13],main:[0,4,5,7,11,12,13,17,18],mainfest:[0,5,7,12,13,18],manag:[0,1,7,8,13,14],mani:[3,10],manifest:6,master:[3,10],masteraddress:[0,7,13],math:[4,11,17],maxdur:[13,19],md:[0,2,7,9,13,15],memori:[0,3,7,10,13],memorydump:[0,1,7,13],memorydur:[3,10],memoryfil:[0,7,13],messag:[4,11,17],messageformat:[0,7,13],meta:[3,4,10,11,17],methodhandl:[0,7,13],methodtyp:[0,7,13],mit:[3,10,16],mm:[4,11,17],mockj:[4,11,17],mocktempl:[3,6,10],modul:[5,12,18],mongo:[4,11,17],mongocli:[4,11,17],mongodb:[4,11,17],mongodbexampl:[4,11,17],mongodbutil:6,monitor:[0,7,13],moor:[4,11,17],most:[4,11],msg:[0,4,7,11,13,17],msghand:0,msghandler:[0,7,13],msgnjtox:[4,11,17],mysql:[4,11,17],mysqlexampl:[4,11,17],mysqlfromtempl:[0,7,13],mysqlutil:[3,4,10,11],na:[4,11,17],nac:[0,7,13],name:[0,4,5,7,11,12,13,17,18,19],nanningdatasourc:[0,7,13],nashorn:[0,3,7,10,13,16],nc:[3,10],ncontract:[0,7,13],ncstart:[2,9,15],need:[13,19],needrend:[5,12,18],needseq:[0,7,13],neither:[13,19],netti:[3,10,16],never:[13,19],newel:[4,11,17],newiter:[4,11,17],newnodenam:[0,7,13],newunit1:[0,7,13],next:[4,11,17],node1:[0,7,13],node2:[0,7,13],node3:[0,7,13],node:[0,7],node_180:[0,7,13],nodecenterw:[0,7,13],nodecenterwebsocket:[0,7,13],nodeconfig:1,nodeconfigchang:1,nodeinstanceslist:1,nodeinstancespag:1,nodelic:1,nodemanag:[0,2,7,9,13,15],nodenam:[0,7,13],nodeport:[0,1,3,7,8,10,13,14],nodepubkei:[0,7,13],nodeunit:1,nonc:[13,19],none:[13,19],nor:[13,19],not:[13,19],note:[13,19],notifi:[0,7,13],now:[13,19],number:[4,11,17],obj:[4,11,17],object:[0,5,6,7,12,13,18],of:[13,19],offlin:[0,1,7,8,13,14],offset:[0,4,7,11,13,17],offsetlen:[4,11,17],ok:[13,19],oliv:[0,7,13],onairpurifiermodechang:[0,7,13],onapplyrol:[0,7,13],onauthnoderol:[0,7,13],onc:[4,11],onchangebdledg:[0,7,13],onchangenodecent:[0,7,13],onchangenodenam:[0,7,13],onchangepubl:[0,7,13],onchangeyjspath:[0,7,13],onclick:[5,12,18],oncoderesult:[0,7,13],oncompil:[0,7,13],oncountcontractloggroupbycategori:[0,7,13],oncountnodeloggroupbycategori:[0,7,13],oncreat:[4,5,11,12,17,18],oncreatetrustunit:[0,7,13],ondelet:[0,7,13],ondeletefil:[0,7,13],ondeleterol:[0,7,13],ondeletetrustunit:[0,7,13],ondistributecontract:[0,7,13],onexecuteresult:[0,7,13],ongetnodeid:[0,7,13],ongetnodetrustunit:[0,7,13],ongetrol:[0,7,13],ongetsessionid:[0,7,13],onkillallcontract:[0,7,13],onli:[4,11,13,19],onlin:[0,1,7,8,13,14],onlineid:[3,10],onlistallauthrol:[0,7,13],onlistallus:[0,7,13],onlistapplylist:[0,7,13],onlistcontractprocess:[0,7,13],onlistmemoryfil:[0,7,13],onlistnod:[0,7,13],onlistproject:[0,7,13],onlisttrustunit:[0,7,13],onlistunauthrol:[0,7,13],onloadnodeconfig:[0,7,13],onlockedit:[0,7,13],onlogin:[0,7,13],only_onc:4,onopenhandl:[0,7,13],onoutputstream:[0,7,13],onqueryactionlog:[0,7,13],onquerycontractlogbykei:[0,7,13],onquerycontractlogs:[0,7,13],onquerydatabyhash:[0,7,13],onqueryhash:[0,7,13],onqueryhashs:[0,7,13],onquerynodelogbyd:[0,7,13],onquerynodelogbyoffset:[0,7,13],onquerynodelogs:[0,7,13],onqueryrecentcontractlog:[0,7,13],onqueryuserstat:[0,7,13],onsessionid:[0,7,13],onstartcontract:[0,7,13],onstartcontractp2ptrustfulli:[0,7,13],onstaticverifyresult:[0,7,13],ontemplatelist:[0,7,13],ontransferto:[0,7,13],onunlockedit:[0,7,13],onuploadfil:[0,7,13],onuploadlic:[0,7,13],onwritedyj:[0,7,13],open:[3,10],openjdk:[2,9,15],oper:[0,4,7,11,13,17],option:[0,7,13],or:[13,19],oracl:[4,11,17],oracledriv:[4,11],order:[0,7,13],org:[4,11],origin:[0,7,13],ow2:[3,10,16],own:[5,12,18],owner:[0,7,13],ownerhandl:[0,7,13],p2p:[3,10],packag:[5,12,18],packet:[0,7,13],param:[0,1,6,7,8,13,14],parent:[4,11,17],parenthash:[13,19],pars:[4,5,11,12,17,18],password:[4,11,17],path:[0,4,7,11,13,17],pathnam:[3,10],pbft:[3,10],peer:[0,7,13],peerid:[0,1,7,8,13,14],peersid:[0,7,13],permiss:[5,6,12,18],persist:[0,7,13],ping:6,pkg:[5,12,18],point:[5,12,18],pong:[0,7,13],pop:[0,7,13],port:[0,4,7,11,13,17,19],post:[0,7,13,19],postgresql:[4,11],print:[0,4,5,7,11,12,13,17,18],println:[4,11,17],printstream:[4,11,17],printtimetravellog:[0,7,13],printtransferlog:[0,7,13],privatedir:[0,7,13],privatekei:[0,4,7,11,13,17],privatetab:[0,7,13],process:[13,19],progress:[0,4,7,11,13,17],project:[0,3,5,7,10,12,13,16,18],projectnam:[0,7,13],projectscript:[0,7,13],protocolvers:[0,7,13],provinc:[4,11],pshvmokf0sjexk:[13,19],pub1:[4,11,17],pub2:[4,11,17],pub3:[4,11],pub:[5,12,18],pubev:6,pubeventconstraint:6,pubkei:[0,7,13],publickei:[0,4,7,11,13,17],push:[4,11,17],put:[4,11,17],pwd:[4,11,17],pydepend:[5,12,18],python:[3,6,10],queri:[4,5,11,12,17,18],queryactionlog:[0,7,13],querybyoffset:[4,11,17],querybystarttim:[4,11,17],querycmlog:[0,7,13],querycontractinstancedoi:[0,7,13],querycontractlogbyd:[0,7,13],querycontractlogbykei:[0,7,13],querycontractlogbyoffset:[0,7,13],querycontractlogdetail:[0,7,13],querycontractlogs:[0,7,13],querycontractresourceinfo:[0,7,13],querydatabyhash:[0,7,13],querydatabyhashloc:[0,7,13],querydatafromcontract:[5,12,18],querydb:[4,11,17],queryfreeresourceinfo:[0,7,13],queryhashbyoffset:[0,7,13],queryhashbyrequestid:[0,7,13],queryhashs:[0,7,13],queryledg:[0,7,13],querynodelogbyd:[0,7,13],querynodelogbyoffset:[0,7,13],querynodelogs:[0,7,13],queryrol:[0,7,13],querytransactionbyhash:[0,7,13],queryuserstat:[0,7,13],rang:[13,19],raw:4,rbac:[0,7,13],readi:[0,7,13],readm:[0,2,7,9,13,15],readonli:[4,11,17],readthedoc:[3,10,16],rebuildcontractlogindex:[0,7,13],rebuildhashindex:[0,7,13],rebuildnodelogindex:[0,7,13],receiveev:[0,5,7,12,13,18],receiveseg:[0,7,13],recent:[13,19],recmsg:[0,7,13],record:[13,19],regexp:[4,11,17],region:[4,11],renamefil:[0,7,13],renegoti:[3,10],repo:[4,11,17],repoid:[0,7,13],repositori:[0,4,7,11,13,17],req:[0,4,7,11,13,17],request:[0,5,6,7,12,13,18],requestid:[3,4,10,11,17],requir:[13,19],resourc:[4,5,11,12,17,18],respons:[4,11,13,17,19],responsecod:[4,11,17],responseid:[0,7,13],resposecod:[4,11,17],result:[0,1,5,6,7,8,12,13,14,18],resultcheck:[0,7,13],resultset:[4,11,17],resulttext:[5,12,18],resum:[3,10],ret:[0,4,5,7,11,12,13,17,18],rk0dwmauprg82yvx:[13,19],rkdlyyn5ze2ygzo:[13,19],rocksdb:[3,4,10,11,16,17],rocksdbsampl:[4,11,17],rocksdbutil:6,role:[0,7,13],rpm:[2,9,15],rule:[13,19],runtim:[0,7,13],s0j0m:[13,19],same:[13,19],sampl:[5,12,18],savefil:[0,7,13],scanner:[4,11,17],scexecutor:[0,7,13],scide:[0,7,13],scmanag:[0,7,13],score:[5,12,18],scoreadd:[5,12,18],script:[0,5,7,12,13,18],scriptfunct:[0,4,7,11,13,17],scriptobject:[0,7,13],scriptruntim:[0,7,13],sdk:[3,6,10],second:[0,7,13],seektofirst:[4,11,17],select:[4,11,17],selector:[13,19],selfdefinedannt:[5,12,18],semant:[4,11],send:[0,7,13,19],sendlist:[0,7,13],sendmsg:[4,11,17],sendnextseg:[0,7,13],sendtransact:[0,7],seq:[0,7,13],servic:[13,19],servicedescript:[0,7,13],servicenam:[0,7,13],sessionid:[0,7,13],set:[1,13,19],setlogstag:[0,7,13],setpermiss:[0,7,13],sh:[2,3,9,10,15],shortc:[0,7,13],should:[13,19],sign:[0,7,13],signatur:[0,4,7,11,13,17],size:[0,4,7,11,13,17,19],sjdfiwoehfwoi34:[0,7,13],slave:[0,7,13],sm2:[0,2,3,6,7,9,10,13,15,16],sm2java:[3,10,16],sm2kei:[0,7,13],sm2sampl:[4,11,17],sm2util:[4,11,17],sm3:[3,10],sm:[3,10,16],smartcontract:[0,7,13],socket:[0,7,13],solid:[5,12,18],sourc:[0,4,7,11,13,17],span:[5,12,18],specifi:[13,19],sphinx:[3,10,16],sponsorpeerid:[0,7,13],sql:[4,11,17],sqlutil:6,src:[4,11,17],ssl:[3,10],start:[0,7,13,19],start_timestamp:[13,19],startcontract:[0,7,13],startcontractasdebug:[0,7,13],startcontractbatch:[0,7,13],startcontractbyypk:[0,7,13],startcontractintempzip:[0,7,13],startcontractp2ptrustfulli:[0,7,13],startdat:[4,11,17],starttimestamp:[13,19],statement:[4,11,17],staticverifycontract:[0,7,13],statu:[0,4,7,11,13,17],stmt:[0,7,13],stopallcontract:[0,7,13],stopcontract:[0,7,13],stopmultipointcontractprocess:[0,7,13],storag:[0,7,13],string:[0,4,5,7,11,12,13,17,18,19],stringifi:[0,4,7,11,13,17],subscrib:[0,5,6,7,12,13,18],success:[0,4,7,11,13,17],sudo:[3,10],support:[13,19],susan:[4,11,17],swap:[0,7,13],tab:[0,7,13],tablenam:[0,4,7,11,13,17],tag:[0,7,13],target:[0,7,13],taskfun:[4,11,17],tcp:[0,7,13],templat:[3,10],tencent:[4,11,17],test1:[0,7,13],test:[0,3,6,7,10,13,19],testexecutorcontract:[4,11,17],testyj:[0,7,13],texport:[0,7,13],text:[0,7,13],than:[13,19],the:[13,19],thei:[13,19],then:[13,19],thi:[5,12,18],time:[0,4,7,11,13,17],timestamp:[0,7,13,19],timetravel:[0,1,7,8,13,14],to:[0,4,7,11,13,17,19],todo:[3,5,10,12,18],tojson:[4,11,17],too:[3,10],tool:[3,10],topic:[4,11,17],total:[5,12,18],totalga:[0,7,13],tprint:[0,7,13],tracetest:[0,7,13],traffic:[0,7,13],transact:[4,11,13,17,19],transactioncount:[13,19],transactionhash:[13,19],transactionsroot:[13,19],treeapi:[3,10,16],tret:[0,7,13],treturn:[0,7,13],trust:[0,7,13],tvar:[0,7,13],txt:[4,5,11,12,17,18],type:[0,4,5,7,11,12,13,17,18,19],u003d:[0,7,13],u003dl0:[0,7,13],u003dl1:[0,7,13],u003dl2:[0,7,13],u003dl3:[0,7,13],u003dl4:[0,7,13],u003dl5:[0,7,13],u003dl6:[0,7,13],u003dl7:[0,7,13],u003dyancloudutil:[0,7,13],ubuntu:[2,9,15],udp:[1,3,8,10,14],udpid:[0,1,7,8,13,14],ui:[3,10,16],undefin:[0,4,7,11,13,17],unlockedit:[0,7,13],unzip:[2,9,15],updat:[3,10],updateclust:[2,9,15],updateconfig:[0,3,7,10,13],updatecontract:[0,2,7,9,13,15],updatelic:[0,7,13],upload:[0,7,13],uploadfil:[0,7,13],uploadlic:[0,7,13],uri:[0,7,13],uriencod:[0,7,13],url:[0,3,4,7,10,11,13,17,19],urlencod:[0,7,13],user:[0,7,13],userlistcount:[0,7,13],using:[13,19],usrnam:[4,11,17],utf8:[4,11,17],utf:[4,11,17],util:[4,11,17],uuid:[1,8,14],v0:[3,10,13,19],v1:[3,10],val:[0,7,13],valu:[0,4,7,11,13,17],valueof:[4,11,17],vanyv4:[13,19],vanyv7wdcr:[13,19],vcg9mu1gsq:[0,7,13],vcg9mu1gsq_bdw:[0,7,13],verifi:[0,7,13],version:[13,19],viewabl:[5,12,18],visitorapi:[3,10,16],vqbea5ee0y5hqeileoquymhbos:[13,19],vs:[5,12,18],w3school:[4,11,17],waimailist:[4,11,17],web:[3,10],webcont:[2,9,15],websocket:[2,3,6,9,10,15,16],websocketsdk:6,wechatimg15:[0,7,13],wed:[0,7,13],wget:[2,9,15],when:[13,19],will:[13,19],william:[4,11,17],wit:[13,19],withdynamicanalysi:[0,7,13],wnfnwoeifnwenef:[0,7,13],word:[4,11],world:[0,4,7,11,13,17],writedyj:[0,7,13],wrp:[0,7,13],ws:[0,1,2,7,8,9,13,14,15],wss:[0,7,13],wssocket:[0,7,13],ww:[4,11,17],www:[0,4,7,11,13,17],xiaomismarthomeatpku:[0,7,13],xx:[4,11,17],xxx:[0,2,4,5,7,9,11,12,13,15,17,18],xxxxx:[0,7,13],xxxxxx:[0,7,13],y29udhjhy3qgdgvzddf7cgllehbvcnqgznvuy3rpb24gagvsbg8oyxjnkxsgciagicagicagcmv0dxjuicj3b3jszci7icakicagih0gicakfq:[0,7,13],yancloud:[4,11,17],yancloudutil:[0,4,5,7,11,12,13,17,18],year:[0,7,13],yjs:[1,2,3,6,8,9,10,14,15],yjsexampl:[5,12,18],yjspath:[0,7,13],young:[4,11,17],your:[5,12,18],ypk:[0,1,3,4,7,8,10,11,13,14,17],yum:[2,9,15],zip:[2,9,15],zjgusl:[4,11,17]},titles:["BDContract SDK","BDContract\u7ba1\u7406\u754c\u9762","BDContract\u5b89\u88c5\u8bf4\u660e","BDContract\u4ecb\u7ecd","YJS SDK","YJS\u8bed\u6cd5","\u5317\u5927\u6570\u745e\u5927\u6570\u636e\u533a\u5757\u94fe \u6587\u6863","BDContract SDK","BDContract\u7ba1\u7406\u754c\u9762","BDContract\u5b89\u88c5\u8bf4\u660e","BDContract\u4ecb\u7ecd","YJS SDK","YJS\u8bed\u6cd5","BDware SDK","\u7ba1\u7406\u754c\u9762","\u5b89\u88c5\u8bf4\u660e","\u5317\u5927\u6570\u745e\u4ecb\u7ecd","YJS SDK","YJS\u8bed\u6cd5","Request Examples {#_request_examples}"],titleterms:{"#_":[13,19],"30":[1,8,14],"\u4e0a\u4f20":[0,1,7,8,13,14],"\u4e0b\u62c9":[1,8,14],"\u4e0b\u62c9\u6846":[1,8,14],"\u4e0b\u8f7d":[0,2,7,9,13,15],"\u4e0e\u975e":[1,8,14],"\u4e2d\u5fc3":[0,7,13],"\u4e3b\u9898":[4,11,17],"\u4e8b\u4ef6":[4,5,11,12,17,18],"\u4ec0\u4e48":[3,10,16],"\u4ecb\u7ecd":[3,10,16],"\u4ee3\u7801":[0,1,7,8,13,14],"\u4eea\u8868":[1,8,14],"\u4eea\u8868\u76d8":[1,8,14],"\u4f20\u81f3":[0,1,7,8,13,14],"\u4f7f\u7528":[1,2,3,4,8,9,10,11,14,15,16,17],"\u4f9d\u8d56":[2,9,15],"\u4fdd\u5b58":[0,7,13],"\u4fe1\u606f":[0,1,7,8,13,14],"\u4fee\u6539":[0,7,13],"\u504f\u79fb":[0,7,13],"\u504f\u79fb\u91cf":[0,7,13],"\u505c\u6b62":[0,1,7,8,13,14],"\u5168\u90e8":[0,1,7,8,13,14],"\u516c\u5171":[0,1,7,8,13,14],"\u5185\u5b58":[0,7,13],"\u5185\u5bb9":[5,12,18],"\u5185\u7f6e":[4,11,17],"\u51c6\u5165":[0,1,2,7,8,9,13,14,15],"\u51fd\u6570":[4,5,11,12,18],"\u5206\u53d1":[0,1,7,8,13,14],"\u5206\u5e03":[0,1,7,8,13,14],"\u5206\u6790":[0,1,7,8,13,14],"\u5206\u7c7b":[1,8,14],"\u5212\u5206":[0,7,13],"\u5217\u8868":[0,1,7,8,13,14],"\u521b\u5efa":[1,8,14],"\u5220\u9664":[0,1,7,8,13,14],"\u524d\u7aef":[4,5,11,12,18],"\u52a0\u89e3\u5bc6":[4,11,17],"\u52a0\u8f7d":[4,11],"\u5317\u5927":[6,16],"\u533a\u5757":6,"\u5347\u7ea7":[2,9,15],"\u5386\u53f2":[0,7,13],"\u5386\u53f2\u8bb0\u5f55":[0,7,13],"\u53c2\u6570":[0,4,7,11,13,17],"\u53c2\u8003":[2,9,15],"\u53d1\u5e03":[4,11,17],"\u53d8\u91cf":[5,12,18],"\u53ef\u4fe1":[0,1,7,8,13,14],"\u53f2\u8bb0":[0,7,13],"\u5404\u7c7b":[1,8,14],"\u5408\u7ea6":[0,1,2,4,7,8,9,11,13,14,15,17],"\u540d\u79f0":[0,7,13],"\u542f\u52a8":[0,1,7,8,13,14],"\u5728\u7ebf":[1,8,14],"\u57fa\u7840":[2,9,15],"\u57fa\u7840\u77e5\u8bc6":[2,9,15],"\u58f0\u660e":[5,12,18],"\u591a\u7ebf":[4,11,17],"\u591a\u7ebf\u7a0b":[4,11,17],"\u5929\u5185":[1,8,14],"\u5b89\u88c5":[0,2,7,9,13,15],"\u5b9a\u4e49":[5,12,18],"\u5b9e\u4f8b":[0,1,7,8,13,14],"\u5bf9\u8c61":[4,11,17],"\u5de5\u5177":[4,11,17],"\u5e73\u53f0":[1,8,14],"\u5e94\u7528":[4,11],"\u5efa\u7acb":[0,7,13],"\u5f00\u6e90":[3,10,16],"\u5f53\u524d":[0,1,7,8,13,14],"\u60c5\u51b5":[1,8,14],"\u6240\u5728":[0,7,13],"\u6240\u6709":[0,7,13],"\u6267\u884c":[0,1,4,7,8,11,13,14,17],"\u6279\u91cf":[0,7,13],"\u62d3\u6251":[2,9,15],"\u6307\u4ee4":[0,7,13],"\u6309\u94ae":[1,8,14],"\u6388\u6743":[0,1,7,8,13,14],"\u63a5\u5165":[0,7,13],"\u63a5\u53e3":[0,7,13],"\u64cd\u4f5c":[0,1,7,8,13,14],"\u6570\u636e":6,"\u6570\u745e":16,"\u6570\u745e\u5927":6,"\u6570\u76ee":[1,8,14],"\u6570\u91cf":[0,7,13],"\u6574\u4f53":[1,8,14],"\u6587\u4ef6":[0,1,2,4,7,8,9,11,13,14,15,17],"\u6587\u6863":6,"\u65b0\u5efa":[1,8,14],"\u65b9\u6cd5":[0,7,13],"\u65e5\u5fd7":[0,1,3,7,8,10,13,14],"\u65e5\u671f":[0,7,13],"\u65f6\u95f4":[0,7,13],"\u65f6\u95f4\u6bb5":[0,7,13],"\u667a\u80fd":[1,2,8,9,14,15],"\u66f4\u65b0":[3,10],"\u672c\u5730":[0,7,13],"\u6743\u9650":[1,8,14],"\u67e5\u770b":[0,7,13],"\u67e5\u8be2":[0,7,13],"\u6839\u636e":[0,7,13],"\u6846\u67b6":[4,11],"\u6982\u89c8":[1,4,8,11,14,17],"\u6982\u8ff0":[5,12,18],"\u6a21\u677f":[0,7,13],"\u6b21\u6570":[0,7,13],"\u6bcf\u65e5":[1,8,14],"\u6ce8\u89e3":[5,12,18],"\u6ce8\u91ca":[5,12,18],"\u6d3b\u8dc3":[1,8,14],"\u6d41\u7a0b":[2,4,9,11,15],"\u6dfb\u52a0":[0,7,13],"\u7279\u70b9":[3,10,16],"\u72b6\u6001":[0,1,7,8,13,14],"\u73af\u5883":[2,9,15],"\u751f\u6210":[0,7,13],"\u7528\u6237":[0,1,7,8,13,14],"\u7533\u8bf7":[0,1,7,8,13,14],"\u754c\u9762":[1,2,8,9,14,15],"\u767b\u5f55":[0,7,13],"\u767e\u5206":[1,8,14],"\u767e\u5206\u6bd4":[1,8,14],"\u76ee\u5f55":[0,7,13],"\u77e5\u8bc6":[2,9,15],"\u793a\u4f8b":[0,4,5,7,11,12,13,17,18],"\u79c1\u6709":[0,7,13],"\u7a7a\u767d":[0,7,13],"\u7ba1\u7406":[0,1,7,8,13,14],"\u7c7b\u578b":[0,1,7,8,13,14],"\u7ea6\u5b9a":[4,11],"\u7ebf\u7a0b":[4,11,17],"\u7ec4\u7f51":[0,7,13],"\u7ec8\u6b62":[0,7,13],"\u7ed3\u6784":[5,12,18],"\u7ed3\u679c":[0,1,7,8,13,14],"\u7edf\u8ba1":[0,1,7,8,13,14],"\u7edf\u8ba1\u56fe":[1,8,14],"\u7f16\u8bd1":[0,7,13],"\u7f16\u8f91":[1,8,14],"\u7f16\u8f91\u5668":[1,8,14],"\u7f51\u7edc":[2,9,15],"\u7f51\u7edc\u62d3\u6251":[2,9,15],"\u811a\u672c":[0,7,13],"\u8282\u70b9":[0,1,2,7,8,9,13,14,15],"\u83b7\u53d6":[0,7,13],"\u83dc\u5355":[1,8,14],"\u8868\u76d8":[1,8,14],"\u89c6\u56fe":[1,8,14],"\u89d2\u8272":[0,7,13],"\u89e3\u5bc6":[4,11,17],"\u89e3\u9501":[0,7,13],"\u8ba2\u9605":[4,11,17],"\u8bb0\u5f55":[0,7,13],"\u8bbe\u7f6e":[1,8,14],"\u8bbf\u95ee":[4,11,17],"\u8bc1\u4e66":[1,8,14],"\u8be6\u60c5":[0,1,7,8,13,14],"\u8bed\u4e49":[4,11],"\u8bed\u6cd5":[5,12,18],"\u8bf4\u660e":[2,3,4,9,10,11,15,16],"\u8bf7\u6c42":[0,7,13],"\u8c03\u7528":[0,1,7,8,13,14],"\u8d26\u53f7":[1,8,14],"\u8d26\u672c":[0,7,13],"\u8d44\u6e90":[4,11,17],"\u8def\u5f84":[0,5,7,12,13,18],"\u8def\u7531":[0,1,2,7,8,9,13,14,15],"\u8f6c\u79fb":[0,7,13],"\u8f93\u51fa":[0,7,13],"\u8fc1\u79fb":[0,1,7,8,13,14],"\u8fd4\u56de":[0,1,7,8,13,14],"\u8fdb\u7a0b":[0,7,13],"\u8fde\u63a5":[0,7,13],"\u901a\u8fc7":[2,9,15],"\u914d\u7f6e":[0,1,7,8,13,14],"\u9501\u5b9a":[0,7,13],"\u96c6\u7fa4":[0,1,7,8,13,14],"\u9759\u6001":[0,1,7,8,13,14],"\u9879\u76ee":[0,1,3,5,7,8,10,12,13,14,16,18],"import":[5,12,18],"in":[4,11,17],_ledger_createledg:[13,19],_ledger_getledg:[13,19],_ledger_sendtransact:[13,19],_node_clientvers:[13,19],_query_countblock:[13,19],_query_counttransact:[13,19],_query_getblock:[13,19],_query_getblockbyhash:[13,19],_query_getrecentblock:[13,19],_query_gettransact:[13,19],_query_gettransactionbyblockhashandindex:[13,19],_query_gettransactionbyhash:[13,19],_request_exampl:19,access:[4,11,17],annot:[4,11,17],api:[4,11,17],asyncutil:[4,11,17],bash:[0,7,13],bdcontract:[0,1,2,3,7,8,9,10],bdware:[2,9,13,15],bdwaretimeseriesdbutil:[4,11,17],build:[4,11,17],call:[4,11,17],clientvers:[13,19],contract:[5,12,18],copyto:[4,11,17],countblock:[13,19],counttransact:[13,19],creat:[4,11,17],createapig:[4,11,17],createledg:[13,19],csv:[0,7,13],delet:[4,11,17],descript:[4,11,17],doiputil:[4,11,17],ecma5:[4,11,17],exampl:19,executecontract:[4,11,17],fileutil:[4,11,17],generatekeypair:[4,11,17],get:[4,11,17],getblock:[13,19],getblockbyhash:[13,19],getclient:[4,11,17],getconnect:[4,11,17],getcont:[4,11,17],getdir:[4,11,17],getfilenam:[4,11,17],getledg:[13,19],getrecentblock:[13,19],gettransact:[13,19],gettransactionbyblockhashandindex:[13,19],gettransactionbyhash:[13,19],global:[4,11,17],hash:[0,7,13],hello:[4,11,17],http:[0,7,13],httputil:[4,11,17],id:[0,7,13],initdriv:[4,11],io:[4,11,17],java:[5,12,18],json:[5,12,18],kei:[0,7,13],ledger:[13,19],ledgerutil:[4,11,17],licenc:[0,1,7,8,13,14],listoper:[4,11,17],loadasinputstream:[4,11,17],loadasscann:[4,11,17],loaddb:[4,11,17],logloc:[4,11,17],logtyp:[4,11,17],manifest:[5,12,18],mocktempl:[4,11,17],mongodbutil:[4,11,17],mysql:[0,7,13],mysqlutil:17,node:[13,19],nodecent:[0,7,13],nodeport:[2,9,15],object:[4,11,17],onlineid:[2,9,15],openfileasprint:[4,11,17],p2p:[1,8,14],param:[4,11,17],permiss:[4,11,17],ping:[0,7,13],post:[4,11,17],postfunct:[4,11,17],pubev:[4,11,17],pubeventconstraint:[4,11],python:[5,12,18],queri:[13,19],querybyhash:[4,11,17],regist:[4,11,17],request:[4,11,17,19],requestid:[0,7,13],reregist:[4,11,17],result:[4,11,17],retriev:[4,11,17],rocksdbutil:[4,11,17],sdk:[0,2,4,7,9,11,13,15,17],sendtransact:[4,11,13,17,19],session:[0,7,13],setinterv:[4,11,17],settimeout:[4,11,17],sign:[4,11,17],sleep:[4,11,17],sm2:[4,11,17],sqlutil:[4,11],subscrib:[4,11,17],test:[4,11,17],updat:[4,11,17],verifi:[4,11,17],websocket:[0,7,13],websocketsdk:[0,7,13],yjs:[0,4,5,7,11,12,13,17,18],zip:[0,7,13]}}) \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100755 index 0000000..56aa953 Binary files /dev/null and b/favicon.ico differ diff --git a/icons/alarm-fill.svg b/icons/alarm-fill.svg new file mode 100755 index 0000000..96e0fd2 --- /dev/null +++ b/icons/alarm-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/alarm.svg b/icons/alarm.svg new file mode 100755 index 0000000..48e3f5f --- /dev/null +++ b/icons/alarm.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/icons/alert-circle-fill.svg b/icons/alert-circle-fill.svg new file mode 100755 index 0000000..aecc6e2 --- /dev/null +++ b/icons/alert-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/alert-circle.svg b/icons/alert-circle.svg new file mode 100755 index 0000000..f6d72d3 --- /dev/null +++ b/icons/alert-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/alert-octagon-fill.svg b/icons/alert-octagon-fill.svg new file mode 100755 index 0000000..6eadd98 --- /dev/null +++ b/icons/alert-octagon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/alert-octagon.svg b/icons/alert-octagon.svg new file mode 100755 index 0000000..eb73071 --- /dev/null +++ b/icons/alert-octagon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/alert-square-fill.svg b/icons/alert-square-fill.svg new file mode 100755 index 0000000..235f2ea --- /dev/null +++ b/icons/alert-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/alert-square.svg b/icons/alert-square.svg new file mode 100755 index 0000000..5f27cb2 --- /dev/null +++ b/icons/alert-square.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/alert-triangle-fill.svg b/icons/alert-triangle-fill.svg new file mode 100755 index 0000000..0bf58af --- /dev/null +++ b/icons/alert-triangle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/alert-triangle.svg b/icons/alert-triangle.svg new file mode 100755 index 0000000..876150b --- /dev/null +++ b/icons/alert-triangle.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/archive-fill.svg b/icons/archive-fill.svg new file mode 100755 index 0000000..0fa4a4b --- /dev/null +++ b/icons/archive-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/archive.svg b/icons/archive.svg new file mode 100755 index 0000000..b4d44f1 --- /dev/null +++ b/icons/archive.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-bar-bottom.svg b/icons/arrow-bar-bottom.svg new file mode 100755 index 0000000..207a860 --- /dev/null +++ b/icons/arrow-bar-bottom.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-bar-left.svg b/icons/arrow-bar-left.svg new file mode 100755 index 0000000..ba3b901 --- /dev/null +++ b/icons/arrow-bar-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-bar-right.svg b/icons/arrow-bar-right.svg new file mode 100755 index 0000000..59fce72 --- /dev/null +++ b/icons/arrow-bar-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-bar-up.svg b/icons/arrow-bar-up.svg new file mode 100755 index 0000000..a777d2c --- /dev/null +++ b/icons/arrow-bar-up.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-clockwise.svg b/icons/arrow-clockwise.svg new file mode 100755 index 0000000..207aa43 --- /dev/null +++ b/icons/arrow-clockwise.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-counterclockwise.svg b/icons/arrow-counterclockwise.svg new file mode 100755 index 0000000..d8874f6 --- /dev/null +++ b/icons/arrow-counterclockwise.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-down-left.svg b/icons/arrow-down-left.svg new file mode 100755 index 0000000..b0395a4 --- /dev/null +++ b/icons/arrow-down-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-down-right.svg b/icons/arrow-down-right.svg new file mode 100755 index 0000000..c2d2812 --- /dev/null +++ b/icons/arrow-down-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-down-short.svg b/icons/arrow-down-short.svg new file mode 100755 index 0000000..bdc3216 --- /dev/null +++ b/icons/arrow-down-short.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-down.svg b/icons/arrow-down.svg new file mode 100755 index 0000000..d5cefb8 --- /dev/null +++ b/icons/arrow-down.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-left-right.svg b/icons/arrow-left-right.svg new file mode 100755 index 0000000..441694d --- /dev/null +++ b/icons/arrow-left-right.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrow-left-short.svg b/icons/arrow-left-short.svg new file mode 100755 index 0000000..91c8cd3 --- /dev/null +++ b/icons/arrow-left-short.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-left.svg b/icons/arrow-left.svg new file mode 100755 index 0000000..ccbde1f --- /dev/null +++ b/icons/arrow-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-repeat.svg b/icons/arrow-repeat.svg new file mode 100755 index 0000000..f662309 --- /dev/null +++ b/icons/arrow-repeat.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrow-right-short.svg b/icons/arrow-right-short.svg new file mode 100755 index 0000000..13067ad --- /dev/null +++ b/icons/arrow-right-short.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-right.svg b/icons/arrow-right.svg new file mode 100755 index 0000000..bc9b753 --- /dev/null +++ b/icons/arrow-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-up-down.svg b/icons/arrow-up-down.svg new file mode 100755 index 0000000..def8cb7 --- /dev/null +++ b/icons/arrow-up-down.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrow-up-left.svg b/icons/arrow-up-left.svg new file mode 100755 index 0000000..834bd9f --- /dev/null +++ b/icons/arrow-up-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-up-right.svg b/icons/arrow-up-right.svg new file mode 100755 index 0000000..0dddbb1 --- /dev/null +++ b/icons/arrow-up-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-up-short.svg b/icons/arrow-up-short.svg new file mode 100755 index 0000000..8d0f2b6 --- /dev/null +++ b/icons/arrow-up-short.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrow-up.svg b/icons/arrow-up.svg new file mode 100755 index 0000000..b3f9b26 --- /dev/null +++ b/icons/arrow-up.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/arrows-angle-contract.svg b/icons/arrows-angle-contract.svg new file mode 100755 index 0000000..d6eed37 --- /dev/null +++ b/icons/arrows-angle-contract.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrows-angle-expand.svg b/icons/arrows-angle-expand.svg new file mode 100755 index 0000000..9fdd51d --- /dev/null +++ b/icons/arrows-angle-expand.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrows-collapse.svg b/icons/arrows-collapse.svg new file mode 100755 index 0000000..c024eda --- /dev/null +++ b/icons/arrows-collapse.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrows-expand.svg b/icons/arrows-expand.svg new file mode 100755 index 0000000..c1d0ee3 --- /dev/null +++ b/icons/arrows-expand.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/arrows-fullscreen.svg b/icons/arrows-fullscreen.svg new file mode 100755 index 0000000..4afdbfb --- /dev/null +++ b/icons/arrows-fullscreen.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/icons/at.svg b/icons/at.svg new file mode 100755 index 0000000..52d5c95 --- /dev/null +++ b/icons/at.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/award.svg b/icons/award.svg new file mode 100755 index 0000000..207c8c5 --- /dev/null +++ b/icons/award.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/backspace-fill.svg b/icons/backspace-fill.svg new file mode 100755 index 0000000..5e5e62b --- /dev/null +++ b/icons/backspace-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/backspace-reverse-fill.svg b/icons/backspace-reverse-fill.svg new file mode 100755 index 0000000..ed92738 --- /dev/null +++ b/icons/backspace-reverse-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/backspace-reverse.svg b/icons/backspace-reverse.svg new file mode 100755 index 0000000..339f4f9 --- /dev/null +++ b/icons/backspace-reverse.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/backspace.svg b/icons/backspace.svg new file mode 100755 index 0000000..689718d --- /dev/null +++ b/icons/backspace.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/bar-chart-fill.svg b/icons/bar-chart-fill.svg new file mode 100755 index 0000000..3ad5ffd --- /dev/null +++ b/icons/bar-chart-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/bar-chart.svg b/icons/bar-chart.svg new file mode 100755 index 0000000..7ec0fee --- /dev/null +++ b/icons/bar-chart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/battery-charging.svg b/icons/battery-charging.svg new file mode 100755 index 0000000..8bf2d93 --- /dev/null +++ b/icons/battery-charging.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/battery-full.svg b/icons/battery-full.svg new file mode 100755 index 0000000..e65cf45 --- /dev/null +++ b/icons/battery-full.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/battery.svg b/icons/battery.svg new file mode 100755 index 0000000..5a80481 --- /dev/null +++ b/icons/battery.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/bell-fill.svg b/icons/bell-fill.svg new file mode 100755 index 0000000..0077288 --- /dev/null +++ b/icons/bell-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/bell.svg b/icons/bell.svg new file mode 100755 index 0000000..834b9c2 --- /dev/null +++ b/icons/bell.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/blockquote-left.svg b/icons/blockquote-left.svg new file mode 100755 index 0000000..99cf7c9 --- /dev/null +++ b/icons/blockquote-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/blockquote-right.svg b/icons/blockquote-right.svg new file mode 100755 index 0000000..c627460 --- /dev/null +++ b/icons/blockquote-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/book-half-fill.svg b/icons/book-half-fill.svg new file mode 100755 index 0000000..7d4c3ba --- /dev/null +++ b/icons/book-half-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/book.svg b/icons/book.svg new file mode 100755 index 0000000..466f0d4 --- /dev/null +++ b/icons/book.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/bookmark-fill.svg b/icons/bookmark-fill.svg new file mode 100755 index 0000000..e1a25e4 --- /dev/null +++ b/icons/bookmark-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/bookmark.svg b/icons/bookmark.svg new file mode 100755 index 0000000..35fd4d2 --- /dev/null +++ b/icons/bookmark.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/bootstrap-fill.svg b/icons/bootstrap-fill.svg new file mode 100755 index 0000000..727764e --- /dev/null +++ b/icons/bootstrap-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/bootstrap-reboot.svg b/icons/bootstrap-reboot.svg new file mode 100755 index 0000000..6563431 --- /dev/null +++ b/icons/bootstrap-reboot.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/bootstrap.svg b/icons/bootstrap.svg new file mode 100755 index 0000000..a10aa70 --- /dev/null +++ b/icons/bootstrap.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/box-arrow-bottom-left.svg b/icons/box-arrow-bottom-left.svg new file mode 100755 index 0000000..5e4e13a --- /dev/null +++ b/icons/box-arrow-bottom-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/box-arrow-bottom-right.svg b/icons/box-arrow-bottom-right.svg new file mode 100755 index 0000000..1ccb4f2 --- /dev/null +++ b/icons/box-arrow-bottom-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/box-arrow-down.svg b/icons/box-arrow-down.svg new file mode 100755 index 0000000..1b28160 --- /dev/null +++ b/icons/box-arrow-down.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/box-arrow-left.svg b/icons/box-arrow-left.svg new file mode 100755 index 0000000..450f552 --- /dev/null +++ b/icons/box-arrow-left.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/box-arrow-right.svg b/icons/box-arrow-right.svg new file mode 100755 index 0000000..4114ff5 --- /dev/null +++ b/icons/box-arrow-right.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/box-arrow-up-left.svg b/icons/box-arrow-up-left.svg new file mode 100755 index 0000000..583225e --- /dev/null +++ b/icons/box-arrow-up-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/box-arrow-up-right.svg b/icons/box-arrow-up-right.svg new file mode 100755 index 0000000..47efabe --- /dev/null +++ b/icons/box-arrow-up-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/box-arrow-up.svg b/icons/box-arrow-up.svg new file mode 100755 index 0000000..2183b4d --- /dev/null +++ b/icons/box-arrow-up.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/braces.svg b/icons/braces.svg new file mode 100755 index 0000000..442e799 --- /dev/null +++ b/icons/braces.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/brightness-fill-high.svg b/icons/brightness-fill-high.svg new file mode 100755 index 0000000..1d0b205 --- /dev/null +++ b/icons/brightness-fill-high.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/brightness-fill-low.svg b/icons/brightness-fill-low.svg new file mode 100755 index 0000000..a7f09dc --- /dev/null +++ b/icons/brightness-fill-low.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/icons/brightness-high.svg b/icons/brightness-high.svg new file mode 100755 index 0000000..2d12b50 --- /dev/null +++ b/icons/brightness-high.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/brightness-low.svg b/icons/brightness-low.svg new file mode 100755 index 0000000..35dd2de --- /dev/null +++ b/icons/brightness-low.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/icons/brush.svg b/icons/brush.svg new file mode 100755 index 0000000..696d2cb --- /dev/null +++ b/icons/brush.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/bucket-fill.svg b/icons/bucket-fill.svg new file mode 100755 index 0000000..4cc1651 --- /dev/null +++ b/icons/bucket-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/bucket.svg b/icons/bucket.svg new file mode 100755 index 0000000..5875c70 --- /dev/null +++ b/icons/bucket.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/building.svg b/icons/building.svg new file mode 100755 index 0000000..380436b --- /dev/null +++ b/icons/building.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/bullseye.svg b/icons/bullseye.svg new file mode 100755 index 0000000..c3d0c6f --- /dev/null +++ b/icons/bullseye.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/calendar-fill.svg b/icons/calendar-fill.svg new file mode 100755 index 0000000..6e23fd8 --- /dev/null +++ b/icons/calendar-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/calendar.svg b/icons/calendar.svg new file mode 100755 index 0000000..93d46b1 --- /dev/null +++ b/icons/calendar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/camera-video-fill.svg b/icons/camera-video-fill.svg new file mode 100755 index 0000000..76aaef0 --- /dev/null +++ b/icons/camera-video-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/camera-video.svg b/icons/camera-video.svg new file mode 100755 index 0000000..2a7bf6c --- /dev/null +++ b/icons/camera-video.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/camera.svg b/icons/camera.svg new file mode 100755 index 0000000..e9b6f88 --- /dev/null +++ b/icons/camera.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/capslock-fill.svg b/icons/capslock-fill.svg new file mode 100755 index 0000000..60c1672 --- /dev/null +++ b/icons/capslock-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/capslock.svg b/icons/capslock.svg new file mode 100755 index 0000000..6478c42 --- /dev/null +++ b/icons/capslock.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chat-fill.svg b/icons/chat-fill.svg new file mode 100755 index 0000000..f0e53e5 --- /dev/null +++ b/icons/chat-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chat.svg b/icons/chat.svg new file mode 100755 index 0000000..de5fdab --- /dev/null +++ b/icons/chat.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/check-box.svg b/icons/check-box.svg new file mode 100755 index 0000000..8a8aafa --- /dev/null +++ b/icons/check-box.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/check-circle.svg b/icons/check-circle.svg new file mode 100755 index 0000000..c025677 --- /dev/null +++ b/icons/check-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/check.svg b/icons/check.svg new file mode 100755 index 0000000..119cd66 --- /dev/null +++ b/icons/check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-compact-down.svg b/icons/chevron-compact-down.svg new file mode 100755 index 0000000..5d17bee --- /dev/null +++ b/icons/chevron-compact-down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-compact-left.svg b/icons/chevron-compact-left.svg new file mode 100755 index 0000000..8064b36 --- /dev/null +++ b/icons/chevron-compact-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-compact-right.svg b/icons/chevron-compact-right.svg new file mode 100755 index 0000000..05fc69f --- /dev/null +++ b/icons/chevron-compact-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-compact-up.svg b/icons/chevron-compact-up.svg new file mode 100755 index 0000000..7103269 --- /dev/null +++ b/icons/chevron-compact-up.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-down.svg b/icons/chevron-down.svg new file mode 100755 index 0000000..39bef88 --- /dev/null +++ b/icons/chevron-down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-left.svg b/icons/chevron-left.svg new file mode 100755 index 0000000..22812bd --- /dev/null +++ b/icons/chevron-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-right.svg b/icons/chevron-right.svg new file mode 100755 index 0000000..aea6428 --- /dev/null +++ b/icons/chevron-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/chevron-up.svg b/icons/chevron-up.svg new file mode 100755 index 0000000..7d7d0c6 --- /dev/null +++ b/icons/chevron-up.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/circle-fill.svg b/icons/circle-fill.svg new file mode 100755 index 0000000..afa21e7 --- /dev/null +++ b/icons/circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/circle-half.svg b/icons/circle-half.svg new file mode 100755 index 0000000..9e65fd3 --- /dev/null +++ b/icons/circle-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/circle-slash.svg b/icons/circle-slash.svg new file mode 100755 index 0000000..2d62a50 --- /dev/null +++ b/icons/circle-slash.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/circle.svg b/icons/circle.svg new file mode 100755 index 0000000..71a395a --- /dev/null +++ b/icons/circle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/clock-fill.svg b/icons/clock-fill.svg new file mode 100755 index 0000000..45069ed --- /dev/null +++ b/icons/clock-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/clock.svg b/icons/clock.svg new file mode 100755 index 0000000..9771264 --- /dev/null +++ b/icons/clock.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/cloud-download.svg b/icons/cloud-download.svg new file mode 100755 index 0000000..63f9620 --- /dev/null +++ b/icons/cloud-download.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/cloud-fill.svg b/icons/cloud-fill.svg new file mode 100755 index 0000000..79d2efa --- /dev/null +++ b/icons/cloud-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/cloud-upload.svg b/icons/cloud-upload.svg new file mode 100755 index 0000000..647737f --- /dev/null +++ b/icons/cloud-upload.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/cloud.svg b/icons/cloud.svg new file mode 100755 index 0000000..00fb0a0 --- /dev/null +++ b/icons/cloud.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/code-slash.svg b/icons/code-slash.svg new file mode 100755 index 0000000..fd41058 --- /dev/null +++ b/icons/code-slash.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/code.svg b/icons/code.svg new file mode 100755 index 0000000..e3b3df3 --- /dev/null +++ b/icons/code.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/columns-gutters.svg b/icons/columns-gutters.svg new file mode 100755 index 0000000..cf23555 --- /dev/null +++ b/icons/columns-gutters.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/columns.svg b/icons/columns.svg new file mode 100755 index 0000000..cf59c51 --- /dev/null +++ b/icons/columns.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/command.svg b/icons/command.svg new file mode 100755 index 0000000..f9565d1 --- /dev/null +++ b/icons/command.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/compass.svg b/icons/compass.svg new file mode 100755 index 0000000..446e5c3 --- /dev/null +++ b/icons/compass.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/cone-striped.svg b/icons/cone-striped.svg new file mode 100755 index 0000000..08dddf5 --- /dev/null +++ b/icons/cone-striped.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/cone.svg b/icons/cone.svg new file mode 100755 index 0000000..a964c5b --- /dev/null +++ b/icons/cone.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/controller.svg b/icons/controller.svg new file mode 100755 index 0000000..dcc3040 --- /dev/null +++ b/icons/controller.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/credit-card.svg b/icons/credit-card.svg new file mode 100755 index 0000000..82e339e --- /dev/null +++ b/icons/credit-card.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/cursor-fill.svg b/icons/cursor-fill.svg new file mode 100755 index 0000000..d235676 --- /dev/null +++ b/icons/cursor-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/cursor.svg b/icons/cursor.svg new file mode 100755 index 0000000..1b6f5ab --- /dev/null +++ b/icons/cursor.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/dash.svg b/icons/dash.svg new file mode 100755 index 0000000..0773b18 --- /dev/null +++ b/icons/dash.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/diamond-half.svg b/icons/diamond-half.svg new file mode 100755 index 0000000..ddefc5f --- /dev/null +++ b/icons/diamond-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/diamond.svg b/icons/diamond.svg new file mode 100755 index 0000000..a63f24d --- /dev/null +++ b/icons/diamond.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/display-fill.svg b/icons/display-fill.svg new file mode 100755 index 0000000..18bec93 --- /dev/null +++ b/icons/display-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/display.svg b/icons/display.svg new file mode 100755 index 0000000..c55f85e --- /dev/null +++ b/icons/display.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/document-code.svg b/icons/document-code.svg new file mode 100755 index 0000000..22d1c01 --- /dev/null +++ b/icons/document-code.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/document-diff.svg b/icons/document-diff.svg new file mode 100755 index 0000000..99a4bd8 --- /dev/null +++ b/icons/document-diff.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/document-richtext.svg b/icons/document-richtext.svg new file mode 100755 index 0000000..9d1b5a8 --- /dev/null +++ b/icons/document-richtext.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/document-spreadsheet.svg b/icons/document-spreadsheet.svg new file mode 100755 index 0000000..64b51fc --- /dev/null +++ b/icons/document-spreadsheet.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/document-text.svg b/icons/document-text.svg new file mode 100755 index 0000000..1e909ac --- /dev/null +++ b/icons/document-text.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/document.svg b/icons/document.svg new file mode 100755 index 0000000..d5e87c1 --- /dev/null +++ b/icons/document.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/documents-alt.svg b/icons/documents-alt.svg new file mode 100755 index 0000000..4e3a2c5 --- /dev/null +++ b/icons/documents-alt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/documents.svg b/icons/documents.svg new file mode 100755 index 0000000..a1f1437 --- /dev/null +++ b/icons/documents.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/dot.svg b/icons/dot.svg new file mode 100755 index 0000000..01b51ab --- /dev/null +++ b/icons/dot.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/download.svg b/icons/download.svg new file mode 100755 index 0000000..f555d4a --- /dev/null +++ b/icons/download.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/egg-fried.svg b/icons/egg-fried.svg new file mode 100755 index 0000000..f0ac59d --- /dev/null +++ b/icons/egg-fried.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/eject-fill.svg b/icons/eject-fill.svg new file mode 100755 index 0000000..39bbaf1 --- /dev/null +++ b/icons/eject-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/eject.svg b/icons/eject.svg new file mode 100755 index 0000000..0b42630 --- /dev/null +++ b/icons/eject.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/envelope-fill.svg b/icons/envelope-fill.svg new file mode 100755 index 0000000..a1b382a --- /dev/null +++ b/icons/envelope-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/envelope-open-fill.svg b/icons/envelope-open-fill.svg new file mode 100755 index 0000000..baf7914 --- /dev/null +++ b/icons/envelope-open-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/envelope-open.svg b/icons/envelope-open.svg new file mode 100755 index 0000000..0c1af8a --- /dev/null +++ b/icons/envelope-open.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/envelope.svg b/icons/envelope.svg new file mode 100755 index 0000000..dd91bec --- /dev/null +++ b/icons/envelope.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/eye-fill.svg b/icons/eye-fill.svg new file mode 100755 index 0000000..d616e4e --- /dev/null +++ b/icons/eye-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/eye-slash-fill.svg b/icons/eye-slash-fill.svg new file mode 100755 index 0000000..5f1d26d --- /dev/null +++ b/icons/eye-slash-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/eye-slash.svg b/icons/eye-slash.svg new file mode 100755 index 0000000..58970d6 --- /dev/null +++ b/icons/eye-slash.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/eye.svg b/icons/eye.svg new file mode 100755 index 0000000..626bdc2 --- /dev/null +++ b/icons/eye.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/filter.svg b/icons/filter.svg new file mode 100755 index 0000000..1594fb6 --- /dev/null +++ b/icons/filter.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/flag-fill.svg b/icons/flag-fill.svg new file mode 100755 index 0000000..18c37f7 --- /dev/null +++ b/icons/flag-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/flag.svg b/icons/flag.svg new file mode 100755 index 0000000..94935d4 --- /dev/null +++ b/icons/flag.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/folder-fill.svg b/icons/folder-fill.svg new file mode 100755 index 0000000..ec0a03b --- /dev/null +++ b/icons/folder-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/folder-symlink-fill.svg b/icons/folder-symlink-fill.svg new file mode 100755 index 0000000..4c775a4 --- /dev/null +++ b/icons/folder-symlink-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/folder-symlink.svg b/icons/folder-symlink.svg new file mode 100755 index 0000000..f93b76d --- /dev/null +++ b/icons/folder-symlink.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/folder.svg b/icons/folder.svg new file mode 100755 index 0000000..3c6106f --- /dev/null +++ b/icons/folder.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/fonts.svg b/icons/fonts.svg new file mode 100755 index 0000000..0f08cfb --- /dev/null +++ b/icons/fonts.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/forward-fill.svg b/icons/forward-fill.svg new file mode 100755 index 0000000..90dcedc --- /dev/null +++ b/icons/forward-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/forward.svg b/icons/forward.svg new file mode 100755 index 0000000..d898094 --- /dev/null +++ b/icons/forward.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/gear-fill.svg b/icons/gear-fill.svg new file mode 100755 index 0000000..1fb967d --- /dev/null +++ b/icons/gear-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/gear-wide-connected.svg b/icons/gear-wide-connected.svg new file mode 100755 index 0000000..2413bce --- /dev/null +++ b/icons/gear-wide-connected.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/gear-wide.svg b/icons/gear-wide.svg new file mode 100755 index 0000000..e44ee89 --- /dev/null +++ b/icons/gear-wide.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/gear.svg b/icons/gear.svg new file mode 100755 index 0000000..6b32358 --- /dev/null +++ b/icons/gear.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/geo.svg b/icons/geo.svg new file mode 100755 index 0000000..c30df6c --- /dev/null +++ b/icons/geo.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/graph-down.svg b/icons/graph-down.svg new file mode 100755 index 0000000..1f1b3e6 --- /dev/null +++ b/icons/graph-down.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/graph-up.svg b/icons/graph-up.svg new file mode 100755 index 0000000..719d3d2 --- /dev/null +++ b/icons/graph-up.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/grid-fill.svg b/icons/grid-fill.svg new file mode 100755 index 0000000..f23d93c --- /dev/null +++ b/icons/grid-fill.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/grid.svg b/icons/grid.svg new file mode 100755 index 0000000..1d5acb4 --- /dev/null +++ b/icons/grid.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/hammer.svg b/icons/hammer.svg new file mode 100755 index 0000000..3ea285f --- /dev/null +++ b/icons/hammer.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/hash.svg b/icons/hash.svg new file mode 100755 index 0000000..6e085f5 --- /dev/null +++ b/icons/hash.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/heart-fill.svg b/icons/heart-fill.svg new file mode 100755 index 0000000..5b6754e --- /dev/null +++ b/icons/heart-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/heart.svg b/icons/heart.svg new file mode 100755 index 0000000..fcc2beb --- /dev/null +++ b/icons/heart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/house-fill.svg b/icons/house-fill.svg new file mode 100755 index 0000000..3deada4 --- /dev/null +++ b/icons/house-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/house.svg b/icons/house.svg new file mode 100755 index 0000000..4c2b232 --- /dev/null +++ b/icons/house.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/image-alt.svg b/icons/image-alt.svg new file mode 100755 index 0000000..8e3eda3 --- /dev/null +++ b/icons/image-alt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/image-fill.svg b/icons/image-fill.svg new file mode 100755 index 0000000..64330cb --- /dev/null +++ b/icons/image-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/image.svg b/icons/image.svg new file mode 100755 index 0000000..d82b41e --- /dev/null +++ b/icons/image.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/images.svg b/icons/images.svg new file mode 100755 index 0000000..aa4197d --- /dev/null +++ b/icons/images.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/inbox-fill.svg b/icons/inbox-fill.svg new file mode 100755 index 0000000..3606911 --- /dev/null +++ b/icons/inbox-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/inbox.svg b/icons/inbox.svg new file mode 100755 index 0000000..ff4102e --- /dev/null +++ b/icons/inbox.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/inboxes-fill.svg b/icons/inboxes-fill.svg new file mode 100755 index 0000000..c53d4cf --- /dev/null +++ b/icons/inboxes-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/inboxes.svg b/icons/inboxes.svg new file mode 100755 index 0000000..397f361 --- /dev/null +++ b/icons/inboxes.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/info-fill.svg b/icons/info-fill.svg new file mode 100755 index 0000000..f2a5aca --- /dev/null +++ b/icons/info-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/info-square-fill.svg b/icons/info-square-fill.svg new file mode 100755 index 0000000..5ecbf3a --- /dev/null +++ b/icons/info-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/info-square.svg b/icons/info-square.svg new file mode 100755 index 0000000..cb57133 --- /dev/null +++ b/icons/info-square.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/info.svg b/icons/info.svg new file mode 100755 index 0000000..bde3c08 --- /dev/null +++ b/icons/info.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/justify-left.svg b/icons/justify-left.svg new file mode 100755 index 0000000..4d36137 --- /dev/null +++ b/icons/justify-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/justify-right.svg b/icons/justify-right.svg new file mode 100755 index 0000000..95431cd --- /dev/null +++ b/icons/justify-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/justify.svg b/icons/justify.svg new file mode 100755 index 0000000..c39ba96 --- /dev/null +++ b/icons/justify.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/kanban-fill.svg b/icons/kanban-fill.svg new file mode 100755 index 0000000..cb1a08d --- /dev/null +++ b/icons/kanban-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/kanban.svg b/icons/kanban.svg new file mode 100755 index 0000000..17082f5 --- /dev/null +++ b/icons/kanban.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/laptop.svg b/icons/laptop.svg new file mode 100755 index 0000000..eb3f0f5 --- /dev/null +++ b/icons/laptop.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/layout-sidebar-reverse.svg b/icons/layout-sidebar-reverse.svg new file mode 100755 index 0000000..fbe8e9c --- /dev/null +++ b/icons/layout-sidebar-reverse.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/layout-sidebar.svg b/icons/layout-sidebar.svg new file mode 100755 index 0000000..81fd899 --- /dev/null +++ b/icons/layout-sidebar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/layout-split.svg b/icons/layout-split.svg new file mode 100755 index 0000000..4feca60 --- /dev/null +++ b/icons/layout-split.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/list-check.svg b/icons/list-check.svg new file mode 100755 index 0000000..1bb57d8 --- /dev/null +++ b/icons/list-check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/list-ol.svg b/icons/list-ol.svg new file mode 100755 index 0000000..f2f908e --- /dev/null +++ b/icons/list-ol.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/list-task.svg b/icons/list-task.svg new file mode 100755 index 0000000..4cb6b05 --- /dev/null +++ b/icons/list-task.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/list-ul.svg b/icons/list-ul.svg new file mode 100755 index 0000000..857d145 --- /dev/null +++ b/icons/list-ul.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/list.svg b/icons/list.svg new file mode 100755 index 0000000..c2235dd --- /dev/null +++ b/icons/list.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/lock-fill.svg b/icons/lock-fill.svg new file mode 100755 index 0000000..73698d7 --- /dev/null +++ b/icons/lock-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/lock.svg b/icons/lock.svg new file mode 100755 index 0000000..3d1d0b4 --- /dev/null +++ b/icons/lock.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/map.svg b/icons/map.svg new file mode 100755 index 0000000..2355521 --- /dev/null +++ b/icons/map.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/mic.svg b/icons/mic.svg new file mode 100755 index 0000000..0147ec7 --- /dev/null +++ b/icons/mic.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/moon.svg b/icons/moon.svg new file mode 100755 index 0000000..31c35b0 --- /dev/null +++ b/icons/moon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/music-player-fill.svg b/icons/music-player-fill.svg new file mode 100755 index 0000000..b3d0eb6 --- /dev/null +++ b/icons/music-player-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/music-player.svg b/icons/music-player.svg new file mode 100755 index 0000000..0869459 --- /dev/null +++ b/icons/music-player.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/option.svg b/icons/option.svg new file mode 100755 index 0000000..b4901ad --- /dev/null +++ b/icons/option.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/outlet.svg b/icons/outlet.svg new file mode 100755 index 0000000..1a0a2da --- /dev/null +++ b/icons/outlet.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/pause-fill.svg b/icons/pause-fill.svg new file mode 100755 index 0000000..a501888 --- /dev/null +++ b/icons/pause-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/pause.svg b/icons/pause.svg new file mode 100755 index 0000000..ef8f7af --- /dev/null +++ b/icons/pause.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/pen.svg b/icons/pen.svg new file mode 100755 index 0000000..27b77bb --- /dev/null +++ b/icons/pen.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/pencil.svg b/icons/pencil.svg new file mode 100755 index 0000000..cdddae7 --- /dev/null +++ b/icons/pencil.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/people-fill.svg b/icons/people-fill.svg new file mode 100755 index 0000000..9f1410d --- /dev/null +++ b/icons/people-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/people.svg b/icons/people.svg new file mode 100755 index 0000000..8bf14c8 --- /dev/null +++ b/icons/people.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/person-fill.svg b/icons/person-fill.svg new file mode 100755 index 0000000..f5ce55a --- /dev/null +++ b/icons/person-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/person.svg b/icons/person.svg new file mode 100755 index 0000000..232f84a --- /dev/null +++ b/icons/person.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/phone-landscape.svg b/icons/phone-landscape.svg new file mode 100755 index 0000000..e5efa9d --- /dev/null +++ b/icons/phone-landscape.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/phone.svg b/icons/phone.svg new file mode 100755 index 0000000..3c5669e --- /dev/null +++ b/icons/phone.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/pie-chart-fill.svg b/icons/pie-chart-fill.svg new file mode 100755 index 0000000..c5b25e6 --- /dev/null +++ b/icons/pie-chart-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/pie-chart.svg b/icons/pie-chart.svg new file mode 100755 index 0000000..60c656c --- /dev/null +++ b/icons/pie-chart.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/play-fill.svg b/icons/play-fill.svg new file mode 100755 index 0000000..f6585fb --- /dev/null +++ b/icons/play-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/play.svg b/icons/play.svg new file mode 100755 index 0000000..ae553e7 --- /dev/null +++ b/icons/play.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/plug.svg b/icons/plug.svg new file mode 100755 index 0000000..0b091bf --- /dev/null +++ b/icons/plug.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/plus.svg b/icons/plus.svg new file mode 100755 index 0000000..8359a2d --- /dev/null +++ b/icons/plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/power.svg b/icons/power.svg new file mode 100755 index 0000000..5268f7e --- /dev/null +++ b/icons/power.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/question-fill.svg b/icons/question-fill.svg new file mode 100755 index 0000000..37307ad --- /dev/null +++ b/icons/question-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/question-square-fill.svg b/icons/question-square-fill.svg new file mode 100755 index 0000000..c641d24 --- /dev/null +++ b/icons/question-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/question-square.svg b/icons/question-square.svg new file mode 100755 index 0000000..946a407 --- /dev/null +++ b/icons/question-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/question.svg b/icons/question.svg new file mode 100755 index 0000000..a0d6f8a --- /dev/null +++ b/icons/question.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/reply-all-fill.svg b/icons/reply-all-fill.svg new file mode 100755 index 0000000..169be08 --- /dev/null +++ b/icons/reply-all-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/reply-all.svg b/icons/reply-all.svg new file mode 100755 index 0000000..0e1e302 --- /dev/null +++ b/icons/reply-all.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/reply-fill.svg b/icons/reply-fill.svg new file mode 100755 index 0000000..39099b8 --- /dev/null +++ b/icons/reply-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/reply.svg b/icons/reply.svg new file mode 100755 index 0000000..57b83c0 --- /dev/null +++ b/icons/reply.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/screwdriver.svg b/icons/screwdriver.svg new file mode 100755 index 0000000..c3e5819 --- /dev/null +++ b/icons/screwdriver.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/search.svg b/icons/search.svg new file mode 100755 index 0000000..626e4b1 --- /dev/null +++ b/icons/search.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/shield-fill.svg b/icons/shield-fill.svg new file mode 100755 index 0000000..43d22b0 --- /dev/null +++ b/icons/shield-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/shield-lock-fill.svg b/icons/shield-lock-fill.svg new file mode 100755 index 0000000..002a0bd --- /dev/null +++ b/icons/shield-lock-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/shield-lock.svg b/icons/shield-lock.svg new file mode 100755 index 0000000..28dbfa6 --- /dev/null +++ b/icons/shield-lock.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/shield-shaded.svg b/icons/shield-shaded.svg new file mode 100755 index 0000000..e918c74 --- /dev/null +++ b/icons/shield-shaded.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/shield.svg b/icons/shield.svg new file mode 100755 index 0000000..2c353d5 --- /dev/null +++ b/icons/shield.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/shift-fill.svg b/icons/shift-fill.svg new file mode 100755 index 0000000..11a5f72 --- /dev/null +++ b/icons/shift-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/shift.svg b/icons/shift.svg new file mode 100755 index 0000000..6975856 --- /dev/null +++ b/icons/shift.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/skip-backward-fill.svg b/icons/skip-backward-fill.svg new file mode 100755 index 0000000..f24b681 --- /dev/null +++ b/icons/skip-backward-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/skip-backward.svg b/icons/skip-backward.svg new file mode 100755 index 0000000..592238c --- /dev/null +++ b/icons/skip-backward.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/skip-end-fill.svg b/icons/skip-end-fill.svg new file mode 100755 index 0000000..15b4bef --- /dev/null +++ b/icons/skip-end-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/skip-end.svg b/icons/skip-end.svg new file mode 100755 index 0000000..903f8ab --- /dev/null +++ b/icons/skip-end.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/skip-forward-fill.svg b/icons/skip-forward-fill.svg new file mode 100755 index 0000000..0e9ad31 --- /dev/null +++ b/icons/skip-forward-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/skip-forward.svg b/icons/skip-forward.svg new file mode 100755 index 0000000..16a745d --- /dev/null +++ b/icons/skip-forward.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/skip-start-fill.svg b/icons/skip-start-fill.svg new file mode 100755 index 0000000..7957d0d --- /dev/null +++ b/icons/skip-start-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/skip-start.svg b/icons/skip-start.svg new file mode 100755 index 0000000..363fc06 --- /dev/null +++ b/icons/skip-start.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/speaker.svg b/icons/speaker.svg new file mode 100755 index 0000000..283ce03 --- /dev/null +++ b/icons/speaker.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/square-fill.svg b/icons/square-fill.svg new file mode 100755 index 0000000..6b40f6c --- /dev/null +++ b/icons/square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/square-half.svg b/icons/square-half.svg new file mode 100755 index 0000000..8f7fb85 --- /dev/null +++ b/icons/square-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/square.svg b/icons/square.svg new file mode 100755 index 0000000..3a6ba96 --- /dev/null +++ b/icons/square.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/star-fill.svg b/icons/star-fill.svg new file mode 100755 index 0000000..2762a9d --- /dev/null +++ b/icons/star-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/star-half.svg b/icons/star-half.svg new file mode 100755 index 0000000..245bd57 --- /dev/null +++ b/icons/star-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/star.svg b/icons/star.svg new file mode 100755 index 0000000..efca49a --- /dev/null +++ b/icons/star.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/stop-fill.svg b/icons/stop-fill.svg new file mode 100755 index 0000000..87c6eda --- /dev/null +++ b/icons/stop-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/stop.svg b/icons/stop.svg new file mode 100755 index 0000000..c98101d --- /dev/null +++ b/icons/stop.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/stopwatch-fill.svg b/icons/stopwatch-fill.svg new file mode 100755 index 0000000..3327bb9 --- /dev/null +++ b/icons/stopwatch-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/stopwatch.svg b/icons/stopwatch.svg new file mode 100755 index 0000000..d3676e7 --- /dev/null +++ b/icons/stopwatch.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/sun.svg b/icons/sun.svg new file mode 100755 index 0000000..f1a6711 --- /dev/null +++ b/icons/sun.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/table.svg b/icons/table.svg new file mode 100755 index 0000000..24683ee --- /dev/null +++ b/icons/table.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/icons/tablet-landscape.svg b/icons/tablet-landscape.svg new file mode 100755 index 0000000..8d2b966 --- /dev/null +++ b/icons/tablet-landscape.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/tablet.svg b/icons/tablet.svg new file mode 100755 index 0000000..d1eb12b --- /dev/null +++ b/icons/tablet.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/tag-fill.svg b/icons/tag-fill.svg new file mode 100755 index 0000000..64bcf4d --- /dev/null +++ b/icons/tag-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/tag.svg b/icons/tag.svg new file mode 100755 index 0000000..9504a3b --- /dev/null +++ b/icons/tag.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/terminal-fill.svg b/icons/terminal-fill.svg new file mode 100755 index 0000000..cfc635e --- /dev/null +++ b/icons/terminal-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/terminal.svg b/icons/terminal.svg new file mode 100755 index 0000000..b83dba4 --- /dev/null +++ b/icons/terminal.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/text-center.svg b/icons/text-center.svg new file mode 100755 index 0000000..10a8c1f --- /dev/null +++ b/icons/text-center.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/text-indent-left.svg b/icons/text-indent-left.svg new file mode 100755 index 0000000..4a48775 --- /dev/null +++ b/icons/text-indent-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/text-indent-right.svg b/icons/text-indent-right.svg new file mode 100755 index 0000000..680cf83 --- /dev/null +++ b/icons/text-indent-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/text-left.svg b/icons/text-left.svg new file mode 100755 index 0000000..e770130 --- /dev/null +++ b/icons/text-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/text-right.svg b/icons/text-right.svg new file mode 100755 index 0000000..f3f584b --- /dev/null +++ b/icons/text-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/three-dots-vertical.svg b/icons/three-dots-vertical.svg new file mode 100755 index 0000000..1d1a2b9 --- /dev/null +++ b/icons/three-dots-vertical.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/three-dots.svg b/icons/three-dots.svg new file mode 100755 index 0000000..ddebbca --- /dev/null +++ b/icons/three-dots.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/toggle-off.svg b/icons/toggle-off.svg new file mode 100755 index 0000000..361c029 --- /dev/null +++ b/icons/toggle-off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/toggle-on.svg b/icons/toggle-on.svg new file mode 100755 index 0000000..308bb81 --- /dev/null +++ b/icons/toggle-on.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/toggles.svg b/icons/toggles.svg new file mode 100755 index 0000000..529691f --- /dev/null +++ b/icons/toggles.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/tools.svg b/icons/tools.svg new file mode 100755 index 0000000..1824f86 --- /dev/null +++ b/icons/tools.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/trash-fill.svg b/icons/trash-fill.svg new file mode 100755 index 0000000..5fb9a25 --- /dev/null +++ b/icons/trash-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/trash.svg b/icons/trash.svg new file mode 100755 index 0000000..9115b02 --- /dev/null +++ b/icons/trash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/triangle-fill.svg b/icons/triangle-fill.svg new file mode 100755 index 0000000..a7eb13b --- /dev/null +++ b/icons/triangle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/triangle-half.svg b/icons/triangle-half.svg new file mode 100755 index 0000000..e29a967 --- /dev/null +++ b/icons/triangle-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/triangle.svg b/icons/triangle.svg new file mode 100755 index 0000000..57b3873 --- /dev/null +++ b/icons/triangle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/trophy.svg b/icons/trophy.svg new file mode 100755 index 0000000..10df539 --- /dev/null +++ b/icons/trophy.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/tv-fill.svg b/icons/tv-fill.svg new file mode 100755 index 0000000..1527a16 --- /dev/null +++ b/icons/tv-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/tv.svg b/icons/tv.svg new file mode 100755 index 0000000..2f8f85a --- /dev/null +++ b/icons/tv.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/type-bold.svg b/icons/type-bold.svg new file mode 100755 index 0000000..445a8c5 --- /dev/null +++ b/icons/type-bold.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/type-h1.svg b/icons/type-h1.svg new file mode 100755 index 0000000..82a7a93 --- /dev/null +++ b/icons/type-h1.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/type-h2.svg b/icons/type-h2.svg new file mode 100755 index 0000000..0e8457e --- /dev/null +++ b/icons/type-h2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/type-h3.svg b/icons/type-h3.svg new file mode 100755 index 0000000..54cf030 --- /dev/null +++ b/icons/type-h3.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/type-italic.svg b/icons/type-italic.svg new file mode 100755 index 0000000..caa0e27 --- /dev/null +++ b/icons/type-italic.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/type-strikethrough.svg b/icons/type-strikethrough.svg new file mode 100755 index 0000000..a895d60 --- /dev/null +++ b/icons/type-strikethrough.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/type-underline.svg b/icons/type-underline.svg new file mode 100755 index 0000000..99266f0 --- /dev/null +++ b/icons/type-underline.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/type.svg b/icons/type.svg new file mode 100755 index 0000000..8d84cea --- /dev/null +++ b/icons/type.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/unlock-fill.svg b/icons/unlock-fill.svg new file mode 100755 index 0000000..13fb085 --- /dev/null +++ b/icons/unlock-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/unlock.svg b/icons/unlock.svg new file mode 100755 index 0000000..55348eb --- /dev/null +++ b/icons/unlock.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/upload.svg b/icons/upload.svg new file mode 100755 index 0000000..1d4b454 --- /dev/null +++ b/icons/upload.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/volume-down-fill.svg b/icons/volume-down-fill.svg new file mode 100755 index 0000000..1e0d235 --- /dev/null +++ b/icons/volume-down-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/volume-down.svg b/icons/volume-down.svg new file mode 100755 index 0000000..304415b --- /dev/null +++ b/icons/volume-down.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/volume-mute-fill.svg b/icons/volume-mute-fill.svg new file mode 100755 index 0000000..2b49b56 --- /dev/null +++ b/icons/volume-mute-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/volume-mute.svg b/icons/volume-mute.svg new file mode 100755 index 0000000..2e8f057 --- /dev/null +++ b/icons/volume-mute.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/volume-up-fill.svg b/icons/volume-up-fill.svg new file mode 100755 index 0000000..f0a15a3 --- /dev/null +++ b/icons/volume-up-fill.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/volume-up.svg b/icons/volume-up.svg new file mode 100755 index 0000000..dc3d5b8 --- /dev/null +++ b/icons/volume-up.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/icons/wallet.svg b/icons/wallet.svg new file mode 100755 index 0000000..f5e3247 --- /dev/null +++ b/icons/wallet.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/watch.svg b/icons/watch.svg new file mode 100755 index 0000000..2bc60f1 --- /dev/null +++ b/icons/watch.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/wifi.svg b/icons/wifi.svg new file mode 100755 index 0000000..68c9c2b --- /dev/null +++ b/icons/wifi.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/window.svg b/icons/window.svg new file mode 100755 index 0000000..5b6fdd1 --- /dev/null +++ b/icons/window.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/wrench.svg b/icons/wrench.svg new file mode 100755 index 0000000..ffa2e9c --- /dev/null +++ b/icons/wrench.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/x-circle-fill.svg b/icons/x-circle-fill.svg new file mode 100755 index 0000000..59ce257 --- /dev/null +++ b/icons/x-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/x-circle.svg b/icons/x-circle.svg new file mode 100755 index 0000000..1b8290b --- /dev/null +++ b/icons/x-circle.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/x-octagon-fill.svg b/icons/x-octagon-fill.svg new file mode 100755 index 0000000..674c8a1 --- /dev/null +++ b/icons/x-octagon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/x-octagon.svg b/icons/x-octagon.svg new file mode 100755 index 0000000..b2c2c9d --- /dev/null +++ b/icons/x-octagon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/x-square-fill.svg b/icons/x-square-fill.svg new file mode 100755 index 0000000..7905f1f --- /dev/null +++ b/icons/x-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/x-square.svg b/icons/x-square.svg new file mode 100755 index 0000000..6638b85 --- /dev/null +++ b/icons/x-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/icons/x.svg b/icons/x.svg new file mode 100755 index 0000000..bffa77a --- /dev/null +++ b/icons/x.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/images/index/analysis.png b/images/index/analysis.png new file mode 100755 index 0000000..8d6b0d0 Binary files /dev/null and b/images/index/analysis.png differ diff --git a/images/index/audit.png b/images/index/audit.png new file mode 100755 index 0000000..16901a5 Binary files /dev/null and b/images/index/audit.png differ diff --git a/images/index/audit_local.png b/images/index/audit_local.png new file mode 100755 index 0000000..f4aad6f Binary files /dev/null and b/images/index/audit_local.png differ diff --git a/images/index/close.png b/images/index/close.png new file mode 100644 index 0000000..cbec6b2 Binary files /dev/null and b/images/index/close.png differ diff --git a/images/index/customer-support.png b/images/index/customer-support.png new file mode 100755 index 0000000..c411c85 Binary files /dev/null and b/images/index/customer-support.png differ diff --git a/images/index/document.png b/images/index/document.png new file mode 100755 index 0000000..363447b Binary files /dev/null and b/images/index/document.png differ diff --git a/images/index/faq.png b/images/index/faq.png new file mode 100755 index 0000000..f43af36 Binary files /dev/null and b/images/index/faq.png differ diff --git a/images/index/migrate.png b/images/index/migrate.png new file mode 100755 index 0000000..a9b1acc Binary files /dev/null and b/images/index/migrate.png differ diff --git a/images/index/network.png b/images/index/network.png new file mode 100755 index 0000000..7e4a689 Binary files /dev/null and b/images/index/network.png differ diff --git a/images/index/nodeManagement.png b/images/index/nodeManagement.png new file mode 100755 index 0000000..1f699bc Binary files /dev/null and b/images/index/nodeManagement.png differ diff --git a/images/index/operation.png b/images/index/operation.png new file mode 100755 index 0000000..94fd972 Binary files /dev/null and b/images/index/operation.png differ diff --git a/images/index/program.png b/images/index/program.png new file mode 100755 index 0000000..bb4ec3d Binary files /dev/null and b/images/index/program.png differ diff --git a/images/index/settings.png b/images/index/settings.png new file mode 100755 index 0000000..33e27d6 Binary files /dev/null and b/images/index/settings.png differ diff --git a/images/index/team.png b/images/index/team.png new file mode 100755 index 0000000..d736be7 Binary files /dev/null and b/images/index/team.png differ diff --git a/images/index/toolbox.png b/images/index/toolbox.png new file mode 100755 index 0000000..cc53464 Binary files /dev/null and b/images/index/toolbox.png differ diff --git a/images/index/trash.png b/images/index/trash.png new file mode 100644 index 0000000..9035304 Binary files /dev/null and b/images/index/trash.png differ diff --git a/images/index/userManagement.png b/images/index/userManagement.png new file mode 100755 index 0000000..0ecace8 Binary files /dev/null and b/images/index/userManagement.png differ diff --git a/images/index/web.png b/images/index/web.png new file mode 100755 index 0000000..57725ee Binary files /dev/null and b/images/index/web.png differ diff --git a/images/index/writer.png b/images/index/writer.png new file mode 100755 index 0000000..b4de9e3 Binary files /dev/null and b/images/index/writer.png differ diff --git a/images/logo-1.png b/images/logo-1.png new file mode 100755 index 0000000..6dd4978 Binary files /dev/null and b/images/logo-1.png differ diff --git a/images/logo.png b/images/logo.png new file mode 100755 index 0000000..ab47958 Binary files /dev/null and b/images/logo.png differ diff --git a/images/logo111.png b/images/logo111.png new file mode 100755 index 0000000..b8d1e55 Binary files /dev/null and b/images/logo111.png differ diff --git a/images/onlineide/analysis.png b/images/onlineide/analysis.png new file mode 100755 index 0000000..399e6db Binary files /dev/null and b/images/onlineide/analysis.png differ diff --git a/images/onlineide/archive.png b/images/onlineide/archive.png new file mode 100644 index 0000000..18b3e25 Binary files /dev/null and b/images/onlineide/archive.png differ diff --git a/images/onlineide/art.png b/images/onlineide/art.png new file mode 100644 index 0000000..9d42f2a Binary files /dev/null and b/images/onlineide/art.png differ diff --git a/images/onlineide/budget.png b/images/onlineide/budget.png new file mode 100755 index 0000000..416feed Binary files /dev/null and b/images/onlineide/budget.png differ diff --git a/images/onlineide/close.png b/images/onlineide/close.png new file mode 100755 index 0000000..254dbe2 Binary files /dev/null and b/images/onlineide/close.png differ diff --git a/images/onlineide/configstart.png b/images/onlineide/configstart.png new file mode 100644 index 0000000..75f1802 Binary files /dev/null and b/images/onlineide/configstart.png differ diff --git a/images/onlineide/data.png b/images/onlineide/data.png new file mode 100644 index 0000000..fea5357 Binary files /dev/null and b/images/onlineide/data.png differ diff --git a/images/onlineide/debug.png b/images/onlineide/debug.png new file mode 100644 index 0000000..c90d90f Binary files /dev/null and b/images/onlineide/debug.png differ diff --git a/images/onlineide/download.png b/images/onlineide/download.png new file mode 100755 index 0000000..240d1c6 Binary files /dev/null and b/images/onlineide/download.png differ diff --git a/images/onlineide/ethernet.png b/images/onlineide/ethernet.png new file mode 100755 index 0000000..63a44f9 Binary files /dev/null and b/images/onlineide/ethernet.png differ diff --git a/images/onlineide/execute.png b/images/onlineide/execute.png new file mode 100755 index 0000000..d1476dc Binary files /dev/null and b/images/onlineide/execute.png differ diff --git a/images/onlineide/file.png b/images/onlineide/file.png new file mode 100755 index 0000000..5fd498e Binary files /dev/null and b/images/onlineide/file.png differ diff --git a/images/onlineide/find.png b/images/onlineide/find.png new file mode 100755 index 0000000..9da487c Binary files /dev/null and b/images/onlineide/find.png differ diff --git a/images/onlineide/folder.png b/images/onlineide/folder.png new file mode 100755 index 0000000..5ffbf74 Binary files /dev/null and b/images/onlineide/folder.png differ diff --git a/images/onlineide/formatter.png b/images/onlineide/formatter.png new file mode 100755 index 0000000..c667f0f Binary files /dev/null and b/images/onlineide/formatter.png differ diff --git a/images/onlineide/kill.png b/images/onlineide/kill.png new file mode 100755 index 0000000..c560387 Binary files /dev/null and b/images/onlineide/kill.png differ diff --git a/images/onlineide/oil-price.png b/images/onlineide/oil-price.png new file mode 100755 index 0000000..6b30f78 Binary files /dev/null and b/images/onlineide/oil-price.png differ diff --git a/images/onlineide/pause.png b/images/onlineide/pause.png new file mode 100755 index 0000000..95b7ff7 Binary files /dev/null and b/images/onlineide/pause.png differ diff --git a/images/onlineide/play.png b/images/onlineide/play.png new file mode 100755 index 0000000..e8fef6e Binary files /dev/null and b/images/onlineide/play.png differ diff --git a/images/onlineide/preview.png b/images/onlineide/preview.png new file mode 100755 index 0000000..2e5bca0 Binary files /dev/null and b/images/onlineide/preview.png differ diff --git a/images/onlineide/price.png b/images/onlineide/price.png new file mode 100755 index 0000000..9e25468 Binary files /dev/null and b/images/onlineide/price.png differ diff --git a/images/onlineide/random.png b/images/onlineide/random.png new file mode 100644 index 0000000..f4de101 Binary files /dev/null and b/images/onlineide/random.png differ diff --git a/images/onlineide/readme.png b/images/onlineide/readme.png new file mode 100644 index 0000000..505a01d Binary files /dev/null and b/images/onlineide/readme.png differ diff --git a/images/onlineide/refresh.png b/images/onlineide/refresh.png new file mode 100755 index 0000000..a9d952f Binary files /dev/null and b/images/onlineide/refresh.png differ diff --git a/images/onlineide/register.png b/images/onlineide/register.png new file mode 100644 index 0000000..eaaa013 Binary files /dev/null and b/images/onlineide/register.png differ diff --git a/images/onlineide/save.png b/images/onlineide/save.png new file mode 100755 index 0000000..31f4a62 Binary files /dev/null and b/images/onlineide/save.png differ diff --git a/images/onlineide/server.png b/images/onlineide/server.png new file mode 100755 index 0000000..7d95ae9 Binary files /dev/null and b/images/onlineide/server.png differ diff --git a/images/onlineide/start.png b/images/onlineide/start.png new file mode 100755 index 0000000..4ea07e0 Binary files /dev/null and b/images/onlineide/start.png differ diff --git a/images/onlineide/stop.png b/images/onlineide/stop.png new file mode 100755 index 0000000..7bfe197 Binary files /dev/null and b/images/onlineide/stop.png differ diff --git a/images/onlineide/trigle.png b/images/onlineide/trigle.png new file mode 100755 index 0000000..e450090 Binary files /dev/null and b/images/onlineide/trigle.png differ diff --git a/images/onlineide/video-files.png b/images/onlineide/video-files.png new file mode 100755 index 0000000..08b3c2c Binary files /dev/null and b/images/onlineide/video-files.png differ diff --git a/images/onlineide/video-player.png b/images/onlineide/video-player.png new file mode 100755 index 0000000..3c20f01 Binary files /dev/null and b/images/onlineide/video-player.png differ diff --git a/images/北大数睿logo@2x.png b/images/北大数睿logo@2x.png new file mode 100755 index 0000000..a0b03da Binary files /dev/null and b/images/北大数睿logo@2x.png differ diff --git a/images/北大数睿logo@3x.png b/images/北大数睿logo@3x.png new file mode 100755 index 0000000..056ebdd Binary files /dev/null and b/images/北大数睿logo@3x.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..22f2963 --- /dev/null +++ b/index.html @@ -0,0 +1,166 @@ + +
+ + + 数瑞智能合约 + + + + + +
+ +
+
+ +
+
+   导航   +
+ +
+
+
+ 说明文档 +
+
+
+ 合约IDE +
+
+
+ 合约节点管理中心 +
+ +
+ + + +
+
+ Icons made by monkik from www.flaticon.com +
+ + + \ No newline at end of file diff --git a/installFromInternetapi.sh b/installFromInternetapi.sh new file mode 100755 index 0000000..b32f9b6 --- /dev/null +++ b/installFromInternetapi.sh @@ -0,0 +1,8 @@ +#!/bin/bash +rm -r bdserver.zip +wget https://contract.internetapi.cn/bdserver.zip +unzip bdserver.zip +cd ./bdserver/ +sh cmstart.sh +echo "Visit http://127.0.0.1:8080/SCIDE/licence.html to config!" +echo "Visit http://127.0.0.1:8080/SCIDE/scide.html to try smart contract ide!" diff --git a/jqueryui1.12/.index.html.swp b/jqueryui1.12/.index.html.swp new file mode 100755 index 0000000..1cdbade Binary files /dev/null and b/jqueryui1.12/.index.html.swp differ diff --git a/jqueryui1.12/AUTHORS.txt b/jqueryui1.12/AUTHORS.txt new file mode 100755 index 0000000..a75056b --- /dev/null +++ b/jqueryui1.12/AUTHORS.txt @@ -0,0 +1,333 @@ +Authors ordered by first contribution +A list of current team members is available at http://jqueryui.com/about + +Paul Bakaus +Richard Worth +Yehuda Katz +Sean Catchpole +John Resig +Tane Piper +Dmitri Gaskin +Klaus Hartl +Stefan Petre +Gilles van den Hoven +Micheil Bryan Smith +Jörn Zaefferer +Marc Grabanski +Keith Wood +Brandon Aaron +Scott González +Eduardo Lundgren +Aaron Eisenberger +Joan Piedra +Bruno Basto +Remy Sharp +Bohdan Ganicky +David Bolter +Chi Cheng +Ca-Phun Ung +Ariel Flesler +Maggie Wachs +Scott Jehl +Todd Parker +Andrew Powell +Brant Burnett +Douglas Neiner +Paul Irish +Ralph Whitbeck +Thibault Duplessis +Dominique Vincent +Jack Hsu +Adam Sontag +Carl Fürstenberg +Kevin Dalman +Alberto Fernández Capel +Jacek Jędrzejewski (http://jacek.jedrzejewski.name) +Ting Kuei +Samuel Cormier-Iijima +Jon Palmer +Ben Hollis +Justin MacCarthy +Eyal Kobrigo +Tiago Freire +Diego Tres +Holger Rüprich +Ziling Zhao +Mike Alsup +Robson Braga Araujo +Pierre-Henri Ausseil +Christopher McCulloh +Andrew Newcomb +Lim Chee Aun +Jorge Barreiro +Daniel Steigerwald +John Firebaugh +John Enters +Andrey Kapitcyn +Dmitry Petrov +Eric Hynds +Chairat Sunthornwiphat +Josh Varner +Stéphane Raimbault +Jay Merrifield +J. Ryan Stinnett +Peter Heiberg +Alex Dovenmuehle +Jamie Gegerson +Raymond Schwartz +Phillip Barnes +Kyle Wilkinson +Khaled AlHourani +Marian Rudzynski +Jean-Francois Remy +Doug Blood +Filippo Cavallarin +Heiko Henning +Aliaksandr Rahalevich +Mario Visic +Xavi Ramirez +Max Schnur +Saji Nediyanchath +Corey Frang +Aaron Peterson +Ivan Peters +Mohamed Cherif Bouchelaghem +Marcos Sousa +Michael DellaNoce +George Marshall +Tobias Brunner +Martin Solli +David Petersen +Dan Heberden +William Kevin Manire +Gilmore Davidson +Michael Wu +Adam Parod +Guillaume Gautreau +Marcel Toele +Dan Streetman +Matt Hoskins +Giovanni Giacobbi +Kyle Florence +Pavol Hluchý +Hans Hillen +Mark Johnson +Trey Hunner +Shane Whittet +Edward A Faulkner +Adam Baratz +Kato Kazuyoshi +Eike Send +Kris Borchers +Eddie Monge +Israel Tsadok +Carson McDonald +Jason Davies +Garrison Locke +David Murdoch +Benjamin Scott Boyle +Jesse Baird +Jonathan Vingiano +Dylan Just +Hiroshi Tomita +Glenn Goodrich +Tarafder Ashek-E-Elahi +Ryan Neufeld +Marc Neuwirth +Philip Graham +Benjamin Sterling +Wesley Walser +Kouhei Sutou +Karl Kirch +Chris Kelly +Jason Oster +Felix Nagel +Alexander Polomoshnov +David Leal +Igor Milla +Dave Methvin +Florian Gutmann +Marwan Al Jubeh +Milan Broum +Sebastian Sauer +Gaëtan Muller +Michel Weimerskirch +William Griffiths +Stojce Slavkovski +David Soms +David De Sloovere +Michael P. Jung +Shannon Pekary +Dan Wellman +Matthew Edward Hutton +James Khoury +Rob Loach +Alberto Monteiro +Alex Rhea +Krzysztof Rosiński +Ryan Olton +Genie <386@mail.com> +Rick Waldron +Ian Simpson +Lev Kitsis +TJ VanToll +Justin Domnitz +Douglas Cerna +Bert ter Heide +Jasvir Nagra +Yuriy Khabarov <13real008@gmail.com> +Harri Kilpiö +Lado Lomidze +Amir E. Aharoni +Simon Sattes +Jo Liss +Guntupalli Karunakar +Shahyar Ghobadpour +Lukasz Lipinski +Timo Tijhof +Jason Moon +Martin Frost +Eneko Illarramendi +EungJun Yi +Courtland Allen +Viktar Varvanovich +Danny Trunk +Pavel Stetina +Michael Stay +Steven Roussey +Michael Hollis +Lee Rowlands +Timmy Willison +Karl Swedberg +Baoju Yuan +Maciej Mroziński +Luis Dalmolin +Mark Aaron Shirley +Martin Hoch +Jiayi Yang +Philipp Benjamin Köppchen +Sindre Sorhus +Bernhard Sirlinger +Jared A. Scheel +Rafael Xavier de Souza +John Chen +Robert Beuligmann +Dale Kocian +Mike Sherov +Andrew Couch +Marc-Andre Lafortune +Nate Eagle +David Souther +Mathias Stenbom +Sergey Kartashov +Avinash R +Ethan Romba +Cory Gackenheimer +Juan Pablo Kaniefsky +Roman Salnikov +Anika Henke +Samuel Bovée +Fabrício Matté +Viktor Kojouharov +Pawel Maruszczyk (http://hrabstwo.net) +Pavel Selitskas +Bjørn Johansen +Matthieu Penant +Dominic Barnes +David Sullivan +Thomas Jaggi +Vahid Sohrabloo +Travis Carden +Bruno M. Custódio +Nathanael Silverman +Christian Wenz +Steve Urmston +Zaven Muradyan +Woody Gilk +Zbigniew Motyka +Suhail Alkowaileet +Toshi MARUYAMA +David Hansen +Brian Grinstead +Christian Klammer +Steven Luscher +Gan Eng Chin +Gabriel Schulhof +Alexander Schmitz +Vilhjálmur Skúlason +Siebrand Mazeland +Mohsen Ekhtiari +Pere Orga +Jasper de Groot +Stephane Deschamps +Jyoti Deka +Andrei Picus +Ondrej Novy +Jacob McCutcheon +Monika Piotrowicz +Imants Horsts +Eric Dahl +Dave Stein +Dylan Barrell +Daniel DeGroff +Michael Wiencek +Thomas Meyer +Ruslan Yakhyaev +Brian J. Dowling +Ben Higgins +Yermo Lamers +Patrick Stapleton +Trisha Crowley +Usman Akeju +Rodrigo Menezes +Jacques Perrault +Frederik Elvhage +Will Holley +Uri Gilad +Richard Gibson +Simen Bekkhus +Chen Eshchar +Bruno Pérel +Mohammed Alshehri +Lisa Seacat DeLuca +Anne-Gaelle Colom +Adam Foster +Luke Page +Daniel Owens +Michael Orchard +Marcus Warren +Nils Heuermann +Marco Ziech +Patricia Juarez +Ben Mosher +Ablay Keldibek +Thomas Applencourt +Jiabao Wu +Eric Lee Carraway +Victor Homyakov +Myeongjin Lee +Liran Sharir +Weston Ruter +Mani Mishra +Hannah Methvin +Leonardo Balter +Benjamin Albert +Michał Gołębiowski +Alyosha Pushak +Fahad Ahmad +Matt Brundage +Francesc Baeta +Piotr Baran +Mukul Hase +Konstantin Dinev +Rand Scullard +Dan Strohl +Maksim Ryzhikov +Amine HADDAD +Amanpreet Singh +Alexey Balchunas +Peter Kehl +Peter Dave Hello +Johannes Schäfer +Ville Skyttä +Ryan Oriecuia diff --git a/jqueryui1.12/LICENSE.txt b/jqueryui1.12/LICENSE.txt new file mode 100755 index 0000000..4819e54 --- /dev/null +++ b/jqueryui1.12/LICENSE.txt @@ -0,0 +1,43 @@ +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-ui + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. diff --git a/jqueryui1.12/datatables.min.css b/jqueryui1.12/datatables.min.css new file mode 100755 index 0000000..1e162e7 --- /dev/null +++ b/jqueryui1.12/datatables.min.css @@ -0,0 +1,572 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#ju/dt-1.10.18 + * + * Included libraries: + * DataTables 1.10.18 + */ +table.dataTable { + width: 100%; + margin: 0 auto; + clear: both; + border-collapse: separate; + border-spacing: 0 +} + +table.dataTable thead th, table.dataTable tfoot th { + font-weight: bold +} + +table.dataTable thead th, table.dataTable thead td { + padding: 10px 18px +} + +table.dataTable thead th:active, table.dataTable thead td:active { + outline: none +} + +table.dataTable tfoot th, table.dataTable tfoot td { + padding: 10px 18px 6px 18px +} + +table.dataTable tbody tr { + background-color: #ffffff +} + +table.dataTable tbody tr.selected { + background-color: #B0BED9 +} + +table.dataTable tbody th, table.dataTable tbody td { + padding: 8px 10px +} + +table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, + table.dataTable.display tbody th, table.dataTable.display tbody td { + border-top: 1px solid #ddd +} + +table.dataTable.row-border tbody tr:first-child th, table.dataTable.row-border tbody tr:first-child td, + table.dataTable.display tbody tr:first-child th, table.dataTable.display tbody tr:first-child td + { + border-top: none +} + +table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td + { + border-top: 1px solid #ddd; + border-right: 1px solid #ddd +} + +table.dataTable.cell-border tbody tr th:first-child, table.dataTable.cell-border tbody tr td:first-child + { + border-left: 1px solid #ddd +} + +table.dataTable.cell-border tbody tr:first-child th, table.dataTable.cell-border tbody tr:first-child td + { + border-top: none +} + +table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd + { + background-color: #f9f9f9 +} + +table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected + { + background-color: #acbad4 +} + +table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover + { + background-color: #f6f6f6 +} + +table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected + { + background-color: #aab7d1 +} + +table.dataTable.order-column tbody tr>.sorting_1, table.dataTable.order-column tbody tr>.sorting_2, + table.dataTable.order-column tbody tr>.sorting_3, table.dataTable.display tbody tr>.sorting_1, + table.dataTable.display tbody tr>.sorting_2, table.dataTable.display tbody tr>.sorting_3 + { + background-color: #fafafa +} + +table.dataTable.order-column tbody tr.selected>.sorting_1, table.dataTable.order-column tbody tr.selected>.sorting_2, + table.dataTable.order-column tbody tr.selected>.sorting_3, table.dataTable.display tbody tr.selected>.sorting_1, + table.dataTable.display tbody tr.selected>.sorting_2, table.dataTable.display tbody tr.selected>.sorting_3 + { + background-color: #acbad5 +} + +table.dataTable.display tbody tr.odd>.sorting_1, table.dataTable.order-column.stripe tbody tr.odd>.sorting_1 + { + background-color: #f1f1f1 +} + +table.dataTable.display tbody tr.odd>.sorting_2, table.dataTable.order-column.stripe tbody tr.odd>.sorting_2 + { + background-color: #f3f3f3 +} + +table.dataTable.display tbody tr.odd>.sorting_3, table.dataTable.order-column.stripe tbody tr.odd>.sorting_3 + { + background-color: whitesmoke +} + +table.dataTable.display tbody tr.odd.selected>.sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1 + { + background-color: #a6b4cd +} + +table.dataTable.display tbody tr.odd.selected>.sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2 + { + background-color: #a8b5cf +} + +table.dataTable.display tbody tr.odd.selected>.sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3 + { + background-color: #a9b7d1 +} + +table.dataTable.display tbody tr.even>.sorting_1, table.dataTable.order-column.stripe tbody tr.even>.sorting_1 + { + background-color: #fafafa +} + +table.dataTable.display tbody tr.even>.sorting_2, table.dataTable.order-column.stripe tbody tr.even>.sorting_2 + { + background-color: #fcfcfc +} + +table.dataTable.display tbody tr.even>.sorting_3, table.dataTable.order-column.stripe tbody tr.even>.sorting_3 + { + background-color: #fefefe +} + +table.dataTable.display tbody tr.even.selected>.sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1 + { + background-color: #acbad5 +} + +table.dataTable.display tbody tr.even.selected>.sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2 + { + background-color: #aebcd6 +} + +table.dataTable.display tbody tr.even.selected>.sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3 + { + background-color: #afbdd8 +} + +table.dataTable.display tbody tr:hover>.sorting_1, table.dataTable.order-column.hover tbody tr:hover>.sorting_1 + { + background-color: #eaeaea +} + +table.dataTable.display tbody tr:hover>.sorting_2, table.dataTable.order-column.hover tbody tr:hover>.sorting_2 + { + background-color: #ececec +} + +table.dataTable.display tbody tr:hover>.sorting_3, table.dataTable.order-column.hover tbody tr:hover>.sorting_3 + { + background-color: #efefef +} + +table.dataTable.display tbody tr:hover.selected>.sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1 + { + background-color: #a2aec7 +} + +table.dataTable.display tbody tr:hover.selected>.sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2 + { + background-color: #a3b0c9 +} + +table.dataTable.display tbody tr:hover.selected>.sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3 + { + background-color: #a5b2cb +} + +table.dataTable.no-footer { + border-bottom: 1px solid #111 +} + +table.dataTable.nowrap th, table.dataTable.nowrap td { + white-space: nowrap +} + +table.dataTable.compact thead th, table.dataTable.compact thead td { + padding: 4px 17px 4px 4px +} + +table.dataTable.compact tfoot th, table.dataTable.compact tfoot td { + padding: 4px +} + +table.dataTable.compact tbody th, table.dataTable.compact tbody td { + padding: 4px +} + +table.dataTable th.dt-left, table.dataTable td.dt-left { + text-align: left +} + +table.dataTable th.dt-center, table.dataTable td.dt-center, table.dataTable td.dataTables_empty + { + text-align: center +} + +table.dataTable th.dt-right, table.dataTable td.dt-right { + text-align: right +} + +table.dataTable th.dt-justify, table.dataTable td.dt-justify { + text-align: justify +} + +table.dataTable th.dt-nowrap, table.dataTable td.dt-nowrap { + white-space: nowrap +} + +table.dataTable thead th.dt-head-left, table.dataTable thead td.dt-head-left, + table.dataTable tfoot th.dt-head-left, table.dataTable tfoot td.dt-head-left + { + text-align: left +} + +table.dataTable thead th.dt-head-center, table.dataTable thead td.dt-head-center, + table.dataTable tfoot th.dt-head-center, table.dataTable tfoot td.dt-head-center + { + text-align: center +} + +table.dataTable thead th.dt-head-right, table.dataTable thead td.dt-head-right, + table.dataTable tfoot th.dt-head-right, table.dataTable tfoot td.dt-head-right + { + text-align: right +} + +table.dataTable thead th.dt-head-justify, table.dataTable thead td.dt-head-justify, + table.dataTable tfoot th.dt-head-justify, table.dataTable tfoot td.dt-head-justify + { + text-align: justify +} + +table.dataTable thead th.dt-head-nowrap, table.dataTable thead td.dt-head-nowrap, + table.dataTable tfoot th.dt-head-nowrap, table.dataTable tfoot td.dt-head-nowrap + { + white-space: nowrap +} + +table.dataTable tbody th.dt-body-left, table.dataTable tbody td.dt-body-left + { + text-align: left +} + +table.dataTable tbody th.dt-body-center, table.dataTable tbody td.dt-body-center + { + text-align: center +} + +table.dataTable tbody th.dt-body-right, table.dataTable tbody td.dt-body-right + { + text-align: right +} + +table.dataTable tbody th.dt-body-justify, table.dataTable tbody td.dt-body-justify + { + text-align: justify +} + +table.dataTable tbody th.dt-body-nowrap, table.dataTable tbody td.dt-body-nowrap + { + white-space: nowrap +} + +table.dataTable, table.dataTable th, table.dataTable td { + box-sizing: content-box +} + +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; + zoom: 1 +} + +.dataTables_wrapper .dataTables_length { + float: left +} + +.dataTables_wrapper .dataTables_filter { + float: right; + text-align: right +} + +.dataTables_wrapper .dataTables_filter input { + margin-left: 0.5em +} + +.dataTables_wrapper .dataTables_info { + clear: both; + float: left; + padding-top: 0.755em +} + +.dataTables_wrapper .dataTables_paginate { + float: right; + text-align: right; + padding-top: 0.25em +} + +.dataTables_wrapper .dataTables_paginate .paginate_button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em 1em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + *cursor: hand; + color: #333 !important; + border: 1px solid transparent; + border-radius: 2px +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.current, + .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover + { + color: #333 !important; + border: 1px solid #979797; + background-color: white; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), + color-stop(100%, #dcdcdc)); + background: -webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%); + background: -moz-linear-gradient(top, #fff 0%, #dcdcdc 100%); + background: -ms-linear-gradient(top, #fff 0%, #dcdcdc 100%); + background: -o-linear-gradient(top, #fff 0%, #dcdcdc 100%); + background: linear-gradient(to bottom, #fff 0%, #dcdcdc 100%) +} + +.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, + .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, + .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active + { + cursor: default; + color: #666 !important; + border: 1px solid transparent; + background: transparent; + box-shadow: none +} + +.dataTables_wrapper .dataTables_paginate .paginate_button:hover { + color: white !important; + border: 1px solid #111; + background-color: #585858; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), + color-stop(100%, #111)); + background: -webkit-linear-gradient(top, #585858 0%, #111 100%); + background: -moz-linear-gradient(top, #585858 0%, #111 100%); + background: -ms-linear-gradient(top, #585858 0%, #111 100%); + background: -o-linear-gradient(top, #585858 0%, #111 100%); + background: linear-gradient(to bottom, #585858 0%, #111 100%) +} + +.dataTables_wrapper .dataTables_paginate .paginate_button:active { + outline: none; + background-color: #2b2b2b; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), + color-stop(100%, #0c0c0c)); + background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); + background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); + box-shadow: inset 0 0 3px #111 +} + +.dataTables_wrapper .dataTables_paginate .ellipsis { + padding: 0 1em +} + +.dataTables_wrapper .dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 40px; + margin-left: -50%; + margin-top: -25px; + padding-top: 20px; + text-align: center; + font-size: 1.2em; + background-color: white; + background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, + 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), + color-stop(75%, rgba(255, 255, 255, 0.9)), + color-stop(100%, rgba(255, 255, 255, 0))); + background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, + rgba(255, 255, 255, 0) 100%); + background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, + rgba(255, 255, 255, 0) 100%); + background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, + rgba(255, 255, 255, 0) 100%); + background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, + rgba(255, 255, 255, 0) 100%); + background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, + rgba(255, 255, 255, 0) 100%) +} + +.dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, + .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, + .dataTables_wrapper .dataTables_paginate { + color: #333 +} + +.dataTables_wrapper .dataTables_scroll { + clear: both +} + +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch +} + +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th, + .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td, + .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th, + .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td + { + vertical-align: middle +} + +.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing, + .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing, + .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing, + .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing + { + height: 0; + overflow: hidden; + margin: 0 !important; + padding: 0 !important +} + +.dataTables_wrapper.no-footer .dataTables_scrollBody { + border-bottom: 1px solid #111 +} + +.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable, + .dataTables_wrapper.no-footer div.dataTables_scrollBody>table { + border-bottom: none +} + +.dataTables_wrapper:after { + visibility: hidden; + display: block; + content: ""; + clear: both; + height: 0 +} + +@media screen and (max-width: 767px) { + .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate + { + float: none; + text-align: center + } + .dataTables_wrapper .dataTables_paginate { + margin-top: 0.5em + } +} + +@media screen and (max-width: 640px) { + .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter + { + float: none; + text-align: center + } + .dataTables_wrapper .dataTables_filter { + margin-top: 0.5em + } +} + +table.dataTable thead th div.DataTables_sort_wrapper { + position: relative +} + +table.dataTable thead th div.DataTables_sort_wrapper span { + position: absolute; + top: 50%; + margin-top: -8px; + right: -18px +} + +table.dataTable thead th.ui-state-default, table.dataTable tfoot th.ui-state-default + { + border-left-width: 0 +} + +table.dataTable thead th.ui-state-default:first-child, table.dataTable tfoot th.ui-state-default:first-child + { + border-left-width: 1px +} + +.dataTables_wrapper .dataTables_paginate .fg-button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + *cursor: hand; + border: 1px solid transparent +} + +.dataTables_wrapper .dataTables_paginate .fg-button:active { + outline: none +} + +.dataTables_wrapper .dataTables_paginate .fg-button:first-child { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px +} + +.dataTables_wrapper .dataTables_paginate .fg-button:last-child { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px +} + +.dataTables_wrapper .ui-widget-header { + font-weight: normal +} + +.dataTables_wrapper .ui-toolbar { + padding: 8px +} + +.dataTables_wrapper.no-footer .dataTables_scrollBody { + border-bottom: none +} + +.dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, + .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_processing, + .dataTables_wrapper .dataTables_paginate { + color: inherit +} \ No newline at end of file diff --git a/jqueryui1.12/datatables.min.js b/jqueryui1.12/datatables.min.js new file mode 100755 index 0000000..a6acb0b --- /dev/null +++ b/jqueryui1.12/datatables.min.js @@ -0,0 +1,191 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#ju/dt-1.10.18 + * + * Included libraries: + * DataTables 1.10.18 + */ + +/*! + DataTables 1.10.18 + ©2008-2018 SpryMedia Ltd - datatables.net/license +*/ +(function(h){"function"===typeof define&&define.amd?define(["jquery"],function(E){return h(E,window,document)}):"object"===typeof exports?module.exports=function(E,H){E||(E=window);H||(H="undefined"!==typeof window?require("jquery"):require("jquery")(E));return h(H,E,E.document)}:h(jQuery,window,document)})(function(h,E,H,k){function Z(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()), +d[c]=e,"o"===b[1]&&Z(a[e])});a._hungarianMap=d}function J(a,b,c){a._hungarianMap||Z(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),J(a[d],b[d],c)):b[d]=b[e]})}function Ca(a){var b=n.defaults.oLanguage,c=b.sDecimal;c&&Da(c);if(a){var d=a.sZeroRecords;!a.sEmptyTable&&(d&&"No data available in table"===b.sEmptyTable)&&F(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(d&&"Loading..."===b.sLoadingRecords)&&F(a, +a,"sZeroRecords","sLoadingRecords");a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&c!==a&&Da(a)}}function eb(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%": +"");"boolean"===typeof a.scrollX&&(a.scrollX=a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b").css({position:"fixed",top:0,left:-1*h(E).scrollLeft(),height:1,width:1, +overflow:"hidden"}).append(h("
").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(h("
").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,n.__browser);a.oScroll.iBarWidth=n.__browser.barWidth} +function hb(a,b,c,d,e,f){var g,j=!1;c!==k&&(g=c,j=!0);for(;d!==e;)a.hasOwnProperty(d)&&(g=j?b(g,a[d],d,a):a[d],j=!0,d+=f);return g}function Ea(a,b){var c=n.defaults.column,d=a.aoColumns.length,c=h.extend({},n.models.oColumn,c,{nTh:b?b:H.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},n.models.oSearch,c[d]);ka(a,d,h(b).data())}function ka(a,b,c){var b=a.aoColumns[b], +d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(fb(c),J(n.defaults.column,c),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),c.sClass&&e.addClass(c.sClass),h.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));var g=b.mData,j=S(g),i=b.mRender? +S(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};b._bAttrSrc=h.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=j(a,b,k,c);return i&&b?i(d,b,a,c):d};b.fnSetData=function(a,b,c){return N(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=d.sSortableNone, +b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function $(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Fa(a);for(var c=0,d=b.length;cq[f])d(l.length+q[f],m);else if("string"=== +typeof q[f]){j=0;for(i=l.length;jb&&a[e]--; -1!=d&&c===k&&a.splice(d, +1)}function da(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ia(a,e,d,d===k?k:e._aData).data;else{var j=e.anCells;if(j)if(d!==k)g(j[d],d);else{c=0;for(f=j.length;c").appendTo(g));b=0;for(c=l.length;btr").attr("role","row");h(g).find(">tr>th, >tr>td").addClass(m.sHeaderTH);h(j).find(">tr>th, >tr>td").addClass(m.sFooterTH);if(null!==j){a=a.aoFooter[0];b=0;for(c=a.length;b=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=-1);var g=a._iDisplayStart,m=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,C(a,!1);else if(j){if(!a.bDestroying&&!lb(a))return}else a.iDraw++;if(0!==i.length){f=j?a.aoData.length:m;for(j=j?0:g;j",{"class":e?d[0]:""}).append(h("",{valign:"top",colSpan:V(a),"class":a.oClasses.sRowEmpty}).html(c))[0];r(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ka(a),g,m,i]);r(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ka(a),g,m,i]);d=h(a.nTBody);d.children().detach(); +d.append(h(b));r(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function T(a,b){var c=a.oFeatures,d=c.bFilter;c.bSort&&mb(a);d?ga(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;P(a);a._drawHold=!1}function nb(a){var b=a.oClasses,c=h(a.nTable),c=h("
").insertBefore(c),d=a.oFeatures,e=h("
",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore= +a.nTable.nextSibling;for(var f=a.sDom.split(""),g,j,i,m,l,q,k=0;k")[0];m=f[k+1];if("'"==m||'"'==m){l="";for(q=2;f[k+q]!=m;)l+=f[k+q],q++;"H"==l?l=b.sJUIHeader:"F"==l&&(l=b.sJUIFooter);-1!=l.indexOf(".")?(m=l.split("."),i.id=m[0].substr(1,m[0].length-1),i.className=m[1]):"#"==l.charAt(0)?i.id=l.substr(1,l.length-1):i.className=l;k+=q}e.append(i);e=h(i)}else if(">"==j)e=e.parent();else if("l"==j&&d.bPaginate&&d.bLengthChange)g=ob(a);else if("f"==j&& +d.bFilter)g=pb(a);else if("r"==j&&d.bProcessing)g=qb(a);else if("t"==j)g=rb(a);else if("i"==j&&d.bInfo)g=sb(a);else if("p"==j&&d.bPaginate)g=tb(a);else if(0!==n.ext.feature.length){i=n.ext.feature;q=0;for(m=i.length;q',j=d.sSearch,j=j.match(/_INPUT_/)?j.replace("_INPUT_", +g):j+g,b=h("
",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("
").addClass(b.sLength);a.aanFeatures.l||(i[0].id=c+"_length");i.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",i).val(a._iDisplayLength).on("change.DT",function(){Ra(a,h(this).val());P(a)});h(a.nTable).on("length.dt.DT",function(b,c,d){a=== +c&&h("select",i).val(d)});return i[0]}function tb(a){var b=a.sPaginationType,c=n.ext.pager[b],d="function"===typeof c,e=function(a){P(a)},b=h("
").addClass(a.oClasses.sPaging+b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,i=a._iDisplayLength,h=a.fnRecordsDisplay(),l=-1===i,b=l?0:Math.ceil(b/i),i=l?1:Math.ceil(h/i),h=c(b,i),k,l=0;for(k=f.p.length;lf&&(d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]} +function C(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");r(a,null,"processing",[a,b])}function rb(a){var b=h(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),j=g.length?g[0]._captionSide:null,i=h(b[0].cloneNode(!1)),m=h(b[0].cloneNode(!1)),l=b.children("tfoot");l.length||(l=null);i=h("
",{"class":f.sScrollWrapper}).append(h("
",{"class":f.sScrollHead}).css({overflow:"hidden", +position:"relative",border:0,width:d?!d?null:v(d):"100%"}).append(h("
",{"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",width:c.sXInner||"100%"}).append(i.removeAttr("id").css("margin-left",0).append("top"===j?g:null).append(b.children("thead"))))).append(h("
",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:v(d)}).append(b));l&&i.append(h("
",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:v(d):"100%"}).append(h("
", +{"class":f.sScrollFootInner}).append(m.removeAttr("id").css("margin-left",0).append("bottom"===j?g:null).append(b.children("tfoot")))));var b=i.children(),k=b[0],f=b[1],t=l?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;l&&(t.scrollLeft=a)});h(f).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=t;a.aoDrawCallback.push({fn:la,sName:"scrolling"});return i[0]}function la(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth, +f=h(a.nScrollHead),g=f[0].style,j=f.children("div"),i=j[0].style,m=j.children("table"),j=a.nScrollBody,l=h(j),q=j.style,t=h(a.nScrollFoot).children("div"),n=t.children("table"),o=h(a.nTHead),p=h(a.nTable),s=p[0],r=s.style,u=a.nTFoot?h(a.nTFoot):null,x=a.oBrowser,U=x.bScrollOversize,Xb=D(a.aoColumns,"nTh"),Q,L,R,w,Ua=[],y=[],z=[],A=[],B,C=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};L=j.scrollHeight>j.clientHeight;if(a.scrollBarVis!== +L&&a.scrollBarVis!==k)a.scrollBarVis=L,$(a);else{a.scrollBarVis=L;p.children("thead, tfoot").remove();u&&(R=u.clone().prependTo(p),Q=u.find("tr"),R=R.find("tr"));w=o.clone().prependTo(p);o=o.find("tr");L=w.find("tr");w.find("th, td").removeAttr("tabindex");c||(q.width="100%",f[0].style.width="100%");h.each(ra(a,w),function(b,c){B=aa(a,b);c.style.width=a.aoColumns[B].sWidth});u&&I(function(a){a.style.width=""},R);f=p.outerWidth();if(""===c){r.width="100%";if(U&&(p.find("tbody").height()>j.offsetHeight|| +"scroll"==l.css("overflow-y")))r.width=v(p.outerWidth()-b);f=p.outerWidth()}else""!==d&&(r.width=v(d),f=p.outerWidth());I(C,L);I(function(a){z.push(a.innerHTML);Ua.push(v(h(a).css("width")))},L);I(function(a,b){if(h.inArray(a,Xb)!==-1)a.style.width=Ua[b]},o);h(L).height(0);u&&(I(C,R),I(function(a){A.push(a.innerHTML);y.push(v(h(a).css("width")))},R),I(function(a,b){a.style.width=y[b]},Q),h(R).height(0));I(function(a,b){a.innerHTML='
'+z[b]+"
";a.childNodes[0].style.height= +"0";a.childNodes[0].style.overflow="hidden";a.style.width=Ua[b]},L);u&&I(function(a,b){a.innerHTML='
'+A[b]+"
";a.childNodes[0].style.height="0";a.childNodes[0].style.overflow="hidden";a.style.width=y[b]},R);if(p.outerWidth()j.offsetHeight||"scroll"==l.css("overflow-y")?f+b:f;if(U&&(j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")))r.width=v(Q-b);(""===c||""!==d)&&K(a,1,"Possible column misalignment",6)}else Q="100%";q.width=v(Q); +g.width=v(Q);u&&(a.nScrollFoot.style.width=v(Q));!e&&U&&(q.height=v(s.offsetHeight+b));c=p.outerWidth();m[0].style.width=v(c);i.width=v(c);d=p.height()>j.clientHeight||"scroll"==l.css("overflow-y");e="padding"+(x.bScrollbarLeft?"Left":"Right");i[e]=d?b+"px":"0px";u&&(n[0].style.width=v(c),t[0].style.width=v(c),t[0].style[e]=d?b+"px":"0px");p.children("colgroup").insertBefore(p.children("thead"));l.scroll();if((a.bSorted||a.bFiltered)&&!a._drawHold)j.scrollTop=0}}function I(a,b,c){for(var d=0,e=0, +f=b.length,g,j;e").appendTo(j.find("tbody"));j.find("thead, tfoot").remove();j.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());j.find("tfoot th, tfoot td").css("width","");m=ra(a,j.find("thead")[0]);for(n=0;n").css({width:o.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(n=0;n").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(j).appendTo(k);f&&g?j.width(g):f?(j.css("width","auto"),j.removeAttr("width"),j.width()").css("width",v(a)).appendTo(b||H.body),d=c[0].offsetWidth;c.remove();return d}function Fb(a, +b){var c=Gb(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?h("").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Gb(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;fd&&(d=c.length,e=f);return e}function v(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function X(a){var b,c,d=[],e=a.aoColumns,f,g,j,i;b=a.aaSortingFixed;c=h.isPlainObject(b);var m=[];f=function(a){a.length&& +!h.isArray(a[0])?m.push(a):h.merge(m,a)};h.isArray(b)&&f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;ae?1:0,0!==c)return"asc"===j.dir?c:-c;c=d[a];e=d[b];return ce?1:0}):i.sort(function(a,b){var c,g,j,i,k=h.length,n=f[a]._aSortData,o=f[b]._aSortData;for(j=0;jg?1:0})}a.bSorted=!0}function Ib(a){for(var b,c,d=a.aoColumns,e=X(a),a=a.oLanguage.oAria,f=0,g=d.length;f/g,"");var i=c.nTh;i.removeAttribute("aria-sort");c.bSortable&&(0e?e+1:3));e=0;for(f=d.length;ee?e+1:3))}a.aLastSort=d}function Hb(a,b){var c=a.aoColumns[b],d=n.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,ba(a,b)));for(var f,g=n.ext.type.order[c.sType+"-pre"],j=0,i=a.aoData.length;j=f.length?[0,c[1]]:c)}));b.search!==k&&h.extend(a.oPreviousSearch,Bb(b.search));if(b.columns){d=0;for(e=b.columns.length;d=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Na(a,b){var c=a.renderer,d=n.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"=== +typeof c?d[c]||d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ia(a,b){var c=[],c=Kb.numbers_length,d=Math.floor(c/2);b<=c?c=Y(0,b):a<=d?(c=Y(0,c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=Y(b-(c-2),b):(c=Y(a-d+2,a+d-1),c.push("ellipsis"),c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function Da(a){h.each({num:function(b){return za(b,a)},"num-fmt":function(b){return za(b,a,Ya)},"html-num":function(b){return za(b, +a,Aa)},"html-num-fmt":function(b){return za(b,a,Aa,Ya)}},function(b,c){x.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(x.type.search[b+a]=x.type.search.html)})}function Lb(a){return function(){var b=[ya(this[n.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return n.ext.internal[a].apply(this,b)}}var n=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new s(ya(this[x.iApiIndex])):new s(this)}; +this.fnAddData=function(a,b){var c=this.api(!0),d=h.isArray(a)&&(h.isArray(a[0])||h.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&la(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a, +b,c){var d=this.api(!0),a=d.rows(a),e=a.settings()[0],h=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,h);(c===k||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};this.fnFilter=function(a,b,c,d,e,h){e=this.api(!0);null===b||b===k?e.search(a,c,d,h):e.column(b).search(a,c,d,h);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data(): +c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]}; +this.fnPageChange=function(a,b){var c=this.api(!0).page(a);(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return ya(this[x.iApiIndex])};this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===k||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===k||e)&&h.columns.adjust(); +(d===k||d)&&h.draw();return 0};this.fnVersionCheck=x.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=x.internal;for(var e in n.ext.internal)e&&(this[e]=Lb(e));this.each(function(){var e={},g=1").appendTo(q)); +p.nTHead=b[0];b=q.children("tbody");b.length===0&&(b=h("").appendTo(q));p.nTBody=b[0];b=q.children("tfoot");if(b.length===0&&a.length>0&&(p.oScroll.sX!==""||p.oScroll.sY!==""))b=h("").appendTo(q);if(b.length===0||b.children().length===0)q.addClass(u.sNoFooter);else if(b.length>0){p.nTFoot=b[0];ea(p.aoFooter,p.nTFoot)}if(g.aaData)for(j=0;j/g,Zb=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,$b=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Ya=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi,M=function(a){return!a||!0===a||"-"===a?!0:!1},Nb=function(a){var b=parseInt(a,10);return!isNaN(b)&& +isFinite(a)?b:null},Ob=function(a,b){Za[b]||(Za[b]=RegExp(Qa(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace(Za[b],"."):a},$a=function(a,b,c){var d="string"===typeof a;if(M(a))return!0;b&&d&&(a=Ob(a,b));c&&d&&(a=a.replace(Ya,""));return!isNaN(parseFloat(a))&&isFinite(a)},Pb=function(a,b,c){return M(a)?!0:!(M(a)||"string"===typeof a)?null:$a(a.replace(Aa,""),b,c)?!0:null},D=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;ea.length)){b=a.slice().sort();for(var c=b[0],d=1,e=b.length;d")[0],Wb=va.textContent!==k,Yb= +/<.*?>/g,Oa=n.util.throttle,Rb=[],w=Array.prototype,ac=function(a){var b,c,d=n.settings,e=h.map(d,function(a){return a.nTable});if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase())return b=h.inArray(a,e),-1!==b?[d[b]]:null;if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?c=h(a):a instanceof h&&(c=a)}else return[];if(c)return c.map(function(){b=h.inArray(this,e);return-1!==b?d[b]:null}).toArray()};s=function(a,b){if(!(this instanceof +s))return new s(a,b);var c=[],d=function(a){(a=ac(a))&&(c=c.concat(a))};if(h.isArray(a))for(var e=0,f=a.length;ea?new s(b[a],this[a]):null},filter:function(a){var b=[];if(w.filter)b=w.filter.call(this,a,this);else for(var c=0,d=this.length;c").addClass(b),h("td",c).addClass(b).html(a)[0].colSpan=V(d),e.push(c[0]))};f(a,b);c._details&&c._details.detach();c._details=h(e); +c._detailsShow&&c._details.insertAfter(c.nTr)}return this});o(["row().child.show()","row().child().show()"],function(){Tb(this,!0);return this});o(["row().child.hide()","row().child().hide()"],function(){Tb(this,!1);return this});o(["row().child.remove()","row().child().remove()"],function(){db(this);return this});o("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var bc=/^([^:]+):(name|visIdx|visible)$/,Ub=function(a,b, +c,d,e){for(var c=[],d=0,f=e.length;d=0?b:g.length+b];if(typeof a==="function"){var e=Ba(c,f);return h.map(g,function(b,f){return a(f,Ub(c,f,0,0,e),i[f])?f:null})}var k=typeof a==="string"?a.match(bc): +"";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],10);if(b<0){var n=h.map(g,function(a,b){return a.bVisible?b:null});return[n[n.length+b]]}return[aa(c,b)];case "name":return h.map(j,function(a,b){return a===k[1]?b:null});default:return[]}if(a.nodeName&&a._DT_CellIndex)return[a._DT_CellIndex.column];b=h(i).filter(a).map(function(){return h.inArray(this,i)}).toArray();if(b.length||!a.nodeName)return b;b=h(a).closest("*[data-dt-column]");return b.length?[b.data("dt-column")]:[]},c,f)}, +1);c.selector.cols=a;c.selector.opts=b;return c});u("columns().header()","column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});u("columns().footer()","column().footer()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});u("columns().data()","column().data()",function(){return this.iterator("column-rows",Ub,1)});u("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData}, +1)});u("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ja(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});u("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ja(a.aoData,e,"anCells",b)},1)});u("columns().visible()","column().visible()",function(a,b){var c=this.iterator("column",function(b,c){if(a===k)return b.aoColumns[c].bVisible;var f=b.aoColumns,g=f[c],j=b.aoData, +i,m,l;if(a!==k&&g.bVisible!==a){if(a){var n=h.inArray(!0,D(f,"bVisible"),c+1);i=0;for(m=j.length;id;return!0};n.isDataTable= +n.fnIsDataTable=function(a){var b=h(a).get(0),c=!1;if(a instanceof n.Api)return!0;h.each(n.settings,function(a,e){var f=e.nScrollHead?h("table",e.nScrollHead)[0]:null,g=e.nScrollFoot?h("table",e.nScrollFoot)[0]:null;if(e.nTable===b||f===b||g===b)c=!0});return c};n.tables=n.fnTables=function(a){var b=!1;h.isPlainObject(a)&&(b=a.api,a=a.visible);var c=h.map(n.settings,function(b){if(!a||a&&h(b.nTable).is(":visible"))return b.nTable});return b?new s(c):c};n.camelToHungarian=J;o("$()",function(a,b){var c= +this.rows(b).nodes(),c=h(c);return h([].concat(c.filter(a).toArray(),c.find(a).toArray()))});h.each(["on","one","off"],function(a,b){o(b+"()",function(){var a=Array.prototype.slice.call(arguments);a[0]=h.map(a[0].split(/\s/),function(a){return!a.match(/\.dt\b/)?a+".dt":a}).join(" ");var d=h(this.tables().nodes());d[b].apply(d,a);return this})});o("clear()",function(){return this.iterator("table",function(a){oa(a)})});o("settings()",function(){return new s(this.context,this.context)});o("init()",function(){var a= +this.context;return a.length?a[0].oInit:null});o("data()",function(){return this.iterator("table",function(a){return D(a.aoData,"_aData")}).flatten()});o("destroy()",function(a){a=a||!1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,f=b.nTBody,g=b.nTHead,j=b.nTFoot,i=h(e),f=h(f),k=h(b.nTableWrapper),l=h.map(b.aoData,function(a){return a.nTr}),o;b.bDestroying=!0;r(b,"aoDestroyCallback","destroy",[b]);a||(new s(b)).columns().visible(!0);k.off(".DT").find(":not(tbody *)").off(".DT"); +h(E).off(".DT-"+b.sInstance);e!=g.parentNode&&(i.children("thead").detach(),i.append(g));j&&e!=j.parentNode&&(i.children("tfoot").detach(),i.append(j));b.aaSorting=[];b.aaSortingFixed=[];wa(b);h(l).removeClass(b.asStripeClasses.join(" "));h("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);f.children().detach();f.append(l);g=a?"remove":"detach";i[g]();k[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),i.css("width",b.sDestroyWidth).removeClass(d.sTable), +(o=b.asDestroyStripes.length)&&f.children().each(function(a){h(this).addClass(b.asDestroyStripes[a%o])}));c=h.inArray(b,n.settings);-1!==c&&n.settings.splice(c,1)})});h.each(["column","row","cell"],function(a,b){o(b+"s().every()",function(a){var d=this.selector.opts,e=this;return this.iterator(b,function(f,g,h,i,m){a.call(e[b](g,"cell"===b?h:d,"cell"===b?d:k),g,h,i,m)})})});o("i18n()",function(a,b,c){var d=this.context[0],a=S(a)(d.oLanguage);a===k&&(a=b);c!==k&&h.isPlainObject(a)&&(a=a[c]!==k?a[c]: +a._);return a.replace("%d",c)});n.version="1.10.18";n.settings=[];n.models={};n.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};n.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};n.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null, +sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};n.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1, +bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+ +a.sInstance+"_"+location.pathname))}catch(b){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"}, +oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:h.extend({}, +n.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};Z(n.defaults);n.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null}; +Z(n.defaults.column);n.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[], +aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button", +iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal: +this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};n.ext=x={buttons:{}, +classes:{},build:"ju/dt-1.10.18",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:n.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:n.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager}); +h.extend(n.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled", +sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"", +sJUIHeader:"",sJUIFooter:""});var Kb=n.ext.pager;h.extend(Kb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,n.ext.renderer,{pageButton:{_:function(a,b,c,d,e, +f){var g=a.oClasses,j=a.oLanguage.oPaginate,i=a.oLanguage.oAria.paginate||{},m,l,n=0,o=function(b,d){var k,s,u,r,v=function(b){Ta(a,b.data.action,true)};k=0;for(s=d.length;k").appendTo(b);o(u,r)}else{m=null;l="";switch(r){case "ellipsis":b.append('');break;case "first":m=j.sFirst;l=r+(e>0?"":" "+g.sPageButtonDisabled);break;case "previous":m=j.sPrevious;l=r+(e>0?"":" "+g.sPageButtonDisabled);break;case "next":m= +j.sNext;l=r+(e",{"class":g.sPageButton+" "+l,"aria-controls":a.sTableId,"aria-label":i[r],"data-dt-idx":n,tabindex:a.iTabIndex,id:c===0&&typeof r==="string"?a.sTableId+"_"+r:null}).html(m).appendTo(b);Wa(u,{action:r},v);n++}}}},s;try{s=h(b).find(H.activeElement).data("dt-idx")}catch(u){}o(h(b).empty(),d);s!==k&&h(b).find("[data-dt-idx="+ +s+"]").focus()}}});h.extend(n.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return $a(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&!Zb.test(a))return null;var b=Date.parse(a);return null!==b&&!isNaN(b)||M(a)?"date":null},function(a,b){var c=b.oLanguage.sDecimal;return $a(a,c,!0)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Pb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Pb(a,c,!0)?"html-num-fmt"+c:null},function(a){return M(a)|| +"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);h.extend(n.ext.type.search,{html:function(a){return M(a)?a:"string"===typeof a?a.replace(Mb," ").replace(Aa,""):""},string:function(a){return M(a)?a:"string"===typeof a?a.replace(Mb," "):a}});var za=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Ob(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};h.extend(x.type.order,{"date-pre":function(a){a=Date.parse(a);return isNaN(a)?-Infinity:a},"html-pre":function(a){return M(a)? +"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return M(a)?"":"string"===typeof a?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return ab?1:0},"string-desc":function(a,b){return ab?-1:0}});Da("");h.extend(!0,n.ext.renderer,{header:{_:function(a,b,c,d){h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc: +c.sSortingClass)}})},jqueryui:function(a,b,c,d){h("
").addClass(d.sSortJUIWrapper).append(b.contents()).append(h("").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass);b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(h[e]== +"asc"?d.sSortJUIAsc:h[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});var Vb=function(a){return"string"===typeof a?a.replace(//g,">").replace(/"/g,"""):a};n.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return Vb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):"";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g, +a)+f+(e||"")}}},text:function(){return{display:Vb}}};h.extend(n.ext.internal,{_fnExternApiFunc:Lb,_fnBuildAjax:sa,_fnAjaxUpdate:lb,_fnAjaxParameters:ub,_fnAjaxUpdateDraw:vb,_fnAjaxDataSrc:ta,_fnAddColumn:Ea,_fnColumnOptions:ka,_fnAdjustColumnSizing:$,_fnVisibleToColumnIndex:aa,_fnColumnIndexToVisible:ba,_fnVisbleColumns:V,_fnGetColumns:ma,_fnColumnTypes:Ga,_fnApplyColumnDefs:ib,_fnHungarianMap:Z,_fnCamelToHungarian:J,_fnLanguageCompat:Ca,_fnBrowserDetect:gb,_fnAddData:O,_fnAddTr:na,_fnNodeToDataIndex:function(a, +b){return b._DT_RowIndex!==k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return h.inArray(c,a.aoData[b].anCells)},_fnGetCellData:B,_fnSetCellData:jb,_fnSplitObjNotation:Ja,_fnGetObjectDataFn:S,_fnSetObjectDataFn:N,_fnGetDataMaster:Ka,_fnClearTable:oa,_fnDeleteIndex:pa,_fnInvalidate:da,_fnGetRowElements:Ia,_fnCreateTr:Ha,_fnBuildHead:kb,_fnDrawHead:fa,_fnDraw:P,_fnReDraw:T,_fnAddOptionsHtml:nb,_fnDetectHeader:ea,_fnGetUniqueThs:ra,_fnFeatureHtmlFilter:pb,_fnFilterComplete:ga,_fnFilterCustom:yb, +_fnFilterColumn:xb,_fnFilter:wb,_fnFilterCreateSearch:Pa,_fnEscapeRegex:Qa,_fnFilterData:zb,_fnFeatureHtmlInfo:sb,_fnUpdateInfo:Cb,_fnInfoMacros:Db,_fnInitialise:ha,_fnInitComplete:ua,_fnLengthChange:Ra,_fnFeatureHtmlLength:ob,_fnFeatureHtmlPaginate:tb,_fnPageChange:Ta,_fnFeatureHtmlProcessing:qb,_fnProcessingDisplay:C,_fnFeatureHtmlTable:rb,_fnScrollDraw:la,_fnApplyToChildren:I,_fnCalculateColumnWidths:Fa,_fnThrottle:Oa,_fnConvertToWidth:Eb,_fnGetWidestNode:Fb,_fnGetMaxLenString:Gb,_fnStringToCss:v, +_fnSortFlatten:X,_fnSort:mb,_fnSortAria:Ib,_fnSortListener:Va,_fnSortAttachListener:Ma,_fnSortingClasses:wa,_fnSortData:Hb,_fnSaveState:xa,_fnLoadState:Jb,_fnSettingsFromNode:ya,_fnLog:K,_fnMap:F,_fnBindAction:Wa,_fnCallbackReg:z,_fnCallbackFire:r,_fnLengthOverflow:Sa,_fnRenderer:Na,_fnDataSource:y,_fnRowAttributes:La,_fnExtend:Xa,_fnCalculateEnd:function(){}});h.fn.dataTable=n;n.$=h;h.fn.dataTableSettings=n.settings;h.fn.dataTableExt=n.ext;h.fn.DataTable=function(a){return h(this).dataTable(a).api()}; +h.each(n,function(a,b){h.fn.DataTable[a]=b});return h.fn.dataTable}); + + +/*! + DataTables jQuery UI integration + ©2011-2014 SpryMedia Ltd - datatables.net/license +*/ +(function(a){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(b){return a(b,window,document)}):"object"===typeof exports?module.exports=function(b,d){b||(b=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(b,d).$;return a(d,b,b.document)}:a(jQuery,window,document)})(function(a){var b=a.fn.dataTable;a.extend(!0,b.defaults,{dom:'<"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-tl ui-corner-tr"lfr>t<"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix ui-corner-bl ui-corner-br"ip>', +renderer:"jqueryui"});a.extend(b.ext.classes,{sWrapper:"dataTables_wrapper dt-jqueryui",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:"ui-state-default sorting_asc",sSortDesc:"ui-state-default sorting_desc",sSortable:"ui-state-default sorting",sSortableAsc:"ui-state-default sorting_asc_disabled",sSortableDesc:"ui-state-default sorting_desc_disabled", +sSortableNone:"ui-state-default sorting_disabled",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollFoot:"dataTables_scrollFoot ui-state-default",sHeaderTH:"ui-state-default",sFooterTH:"ui-state-default"});b.ext.renderer.header.jqueryui=function(b,h,e,c){var f="css_right ui-icon ui-icon-caret-2-n-s",g=-1!==a.inArray("asc",e.asSorting),i=-1!==a.inArray("desc",e.asSorting);!e.bSortable||!g&&!i?f="":g&&!i?f="css_right ui-icon ui-icon-caret-1-n":!g&&i&&(f="css_right ui-icon ui-icon-caret-1-s"); +a("
").addClass("DataTables_sort_wrapper").append(h.contents()).append(a("").addClass(c.sSortIcon+" "+f)).appendTo(h);a(b.nTable).on("order.dt",function(a,g,i,j){b===g&&(a=e.idx,h.removeClass(c.sSortAsc+" "+c.sSortDesc).addClass("asc"==j[a]?c.sSortAsc:"desc"==j[a]?c.sSortDesc:e.sSortingClass),h.find("span."+c.sSortIcon).removeClass("css_right ui-icon ui-icon-triangle-1-n css_right ui-icon ui-icon-triangle-1-s css_right ui-icon ui-icon-caret-2-n-s css_right ui-icon ui-icon-caret-1-n css_right ui-icon ui-icon-caret-1-s").addClass("asc"== +j[a]?"css_right ui-icon ui-icon-triangle-1-n":"desc"==j[a]?"css_right ui-icon ui-icon-triangle-1-s":f))})};b.TableTools&&a.extend(!0,b.TableTools.classes,{container:"DTTT_container ui-buttonset ui-buttonset-multi",buttons:{normal:"DTTT_button ui-button ui-state-default"},collection:{container:"DTTT_collection ui-buttonset ui-buttonset-multi"}});return b}); + + diff --git a/jqueryui1.12/external/jquery/jquery.js b/jqueryui1.12/external/jquery/jquery.js new file mode 100755 index 0000000..7fc60fc --- /dev/null +++ b/jqueryui1.12/external/jquery/jquery.js @@ -0,0 +1,11008 @@ +/*! + * jQuery JavaScript Library v1.12.4 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-05-20T17:17Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +//"use strict"; +var deletedIds = []; + +var document = window.document; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.12.4", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type( obj ) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call( obj, "constructor" ) && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + } catch ( e ) { + + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( !support.ownFirst ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[ j ] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +// JSHint would error on this code due to the Symbol not being defined in ES5. +// Defining this global in .jshintrc would create a danger of using the global +// unguarded in another place, it seems safer to just disable JSHint for these +// three lines. +/* jshint ignore: start */ +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ]; +} +/* jshint ignore: end */ + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.1 + * http://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-10-17 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, nidselect, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; + while ( i-- ) { + groups[i] = nidselect + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( (parent = document.defaultView) && parent.top !== parent ) { + // Support: IE 11 + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + return m ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( (oldCache = uniqueCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + } ); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not; + } ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // init accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt( 0 ) === "<" && + selector.charAt( selector.length - 1 ) === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[ 2 ] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[ 0 ] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof root.ready !== "undefined" ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( pos ? + pos.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[ 0 ], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.uniqueSort( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +} ); +var rnotwhite = ( /\S+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = true; + if ( !memory ) { + self.disable(); + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ) ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( function() { + + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || + ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. + // If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .progress( updateFunc( i, progressContexts, progressValues ) ) + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +} ); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +} ); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || + window.event.type === "load" || + document.readyState === "complete" ) { + + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called + // after the browser event has already occurred. + // Support: IE6-10 + // Older IE sometimes signals "interactive" too soon + if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); + + // If IE event model is used + } else { + + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch ( e ) {} + + if ( top && top.doScroll ) { + ( function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll( "left" ); + } catch ( e ) { + return window.setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + } )(); + } + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownFirst = i === "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery( function() { + + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== "undefined" ) { + + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +} ); + + +( function() { + var div = document.createElement( "div" ); + + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch ( e ) { + support.deleteExpando = false; + } + + // Null elements to avoid leaks in IE. + div = null; +} )(); +var acceptData = function( elem ) { + var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute( "classid" ) === noData; +}; + + + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) && + data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } else { + + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[ i ] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, undefined + } else { + cache[ id ] = undefined; + } +} + +jQuery.extend( { + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + jQuery.data( this, key ); + } ); + } + + return arguments.length > 1 ? + + // Sets one value + this.each( function() { + jQuery.data( this, key, value ); + } ) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each( function() { + jQuery.removeData( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = jQuery._data( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, + // or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); + + +( function() { + var shrinkWrapBlocksVal; + + support.shrinkWrapBlocks = function() { + if ( shrinkWrapBlocksVal != null ) { + return shrinkWrapBlocksVal; + } + + // Will be changed later if needed. + shrinkWrapBlocksVal = false; + + // Minified: var b,c,d + var div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + if ( typeof div.style.zoom !== "undefined" ) { + + // Reset CSS: box-sizing; display; margin; border + div.style.cssText = + + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;" + + "padding:1px;width:1px;zoom:1"; + div.appendChild( document.createElement( "div" ) ).style.width = "5px"; + shrinkWrapBlocksVal = div.offsetWidth !== 3; + } + + body.removeChild( container ); + + return shrinkWrapBlocksVal; + }; + +} )(); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || + !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { return tween.cur(); } : + function() { return jQuery.css( elem, prop, "" ); }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( + elems[ i ], + key, + raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[ 0 ], key ) : emptyGet; +}; +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([\w:-]+)/ ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + +var rleadingWhitespace = ( /^\s+/ ); + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + + "details|dialog|figcaption|figure|footer|header|hgroup|main|" + + "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + + +( function() { + var div = document.createElement( "div" ), + fragment = document.createDocumentFragment(), + input = document.createElement( "input" ); + + // Setup + div.innerHTML = "
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input = document.createElement( "input" ); + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ + support.noCloneEvent = !!div.addEventListener; + + // Support: IE<9 + // Since attributes and properties are the same in IE, + // cleanData must set properties to undefined rather than use removeAttribute + div[ jQuery.expando ] = 1; + support.attributes = !div.getAttribute( jQuery.expando ); +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + + // Support: IE8 + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] +}; + +// Support: IE8-IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== "undefined" ? + context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; + ( elem = elems[ i ] ) != null; + i++ + ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; ( elem = elems[ i ] ) != null; i++ ) { + jQuery._data( + elem, + "globalEval", + !refElements || jQuery._data( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/, + rtbody = / from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[ 1 ] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) && + !tbody.childNodes.length ) { + + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; +} + + +( function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) + for ( i in { submit: true, change: true, focusin: true } ) { + eventName = "on" + i; + + if ( !( support[ i ] = eventName in window ) ) { + + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +} )(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE9 +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && + ( !e || jQuery.event.triggered !== e.type ) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + + // Add elem as a property of the handle fn to prevent a memory leak + // with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && + jQuery._data( cur, "handle" ); + + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( + ( !special._default || + special._default.apply( eventPath.pop(), data ) === false + ) && acceptData( elem ) + ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Support (at least): Chrome, IE9 + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // + // Support: Firefox<=42+ + // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) + if ( delegateCount && cur.nodeType && + ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push( { elem: cur, handlers: matches } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Safari 6-8+ + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split( " " ), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: ( "button buttons clientX clientY fromElement offsetX offsetY " + + "pageX pageY screenX screenY toElement" ).split( " " ), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - + ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - + ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? + original.toElement : + fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + // Piggyback on a donor event to simulate a different one + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + + // Previously, `originalEvent: {}` was set here, so stopPropagation call + // would not be triggered on donor event, since in our own + // jQuery.event.stopPropagation function we had a check for existence of + // originalEvent.stopPropagation method, so, consequently it would be a noop. + // + // Guard for simulated events was moved to jQuery.event.stopPropagation function + // since `originalEvent` should point to the original event for the + // constancy with other events and for more focused logic + } + ); + + jQuery.event.trigger( e, null, elem ); + + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, + // to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( !e || this.isSimulated ) { + return; + } + + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://code.google.com/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +// IE submit delegation +if ( !support.submit ) { + + jQuery.event.special.submit = { + setup: function() { + + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? + + // Support: IE <=8 + // We use jQuery.prop instead of elem.form + // to allow fixing the IE8 delegated submit issue (gh-2332) + // by 3rd party polyfills/workarounds. + jQuery.prop( elem, "form" ) : + undefined; + + if ( form && !jQuery._data( form, "submit" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submitBubble = true; + } ); + jQuery._data( form, "submit", true ); + } + } ); + + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + + // If form was submitted by the user, bubble the event up the tree + if ( event._submitBubble ) { + delete event._submitBubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event ); + } + } + }, + + teardown: function() { + + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.change ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._justChanged = true; + } + } ); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._justChanged && !event.isTrigger ) { + this._justChanged = false; + } + + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event ); + } ); + } + return false; + } + + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event ); + } + } ); + jQuery._data( elem, "change", true ); + } + } ); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || + ( elem.type !== "radio" && elem.type !== "checkbox" ) ) { + + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Support: Firefox +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome, Safari +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + } ); +} + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + }, + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ), + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, + + // Support: IE 10-11, Edge 10240+ + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) ); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName( "tbody" )[ 0 ] || + elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + return elem; +} + +function cloneCopyEvent( src, dest ) { + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android<4.1, PhantomJS<2 + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( + ( node.text || node.textContent || node.innerHTML || "" ) + .replace( rcleanScript, "" ) + ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + elems = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = elems[ i ] ) != null; i++ ) { + + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc( elem ) || + !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( ( !support.noCloneEvent || !support.noCloneChecked ) && + ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) { + + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[ i ] ) { + fixCloneNodeIssues( node, destElements[ i ] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) { + cloneCopyEvent( node, destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + cleanData: function( elems, /* internal */ forceAcceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + attributes = support.attributes, + special = jQuery.event.special; + + for ( ; ( elem = elems[ i ] ) != null; i++ ) { + if ( forceAcceptData || acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // Support: IE<9 + // IE does not allow us to delete expando properties from nodes + // IE creates expando attributes along with the property + // IE does not have a removeAttribute function on Document nodes + if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { + elem.removeAttribute( internalKey ); + + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 + } else { + elem[ internalKey ] = undefined; + } + + deletedIds.push( id ); + } + } + } + } + } +} ); + +jQuery.fn.extend( { + + // Keep domManip exposed until 3.0 (gh-2225) + domManip: domManip, + + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( + ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) + ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + + // Remove element nodes and prevent memory leaks + elem = this[ i ] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); + + +var iframe, + elemdisplay = { + + // Support: Firefox + // We have to pre-define these values for FF (#10227) + HTML: "block", + BODY: "block" + }; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ + +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + display = jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = ( iframe || jQuery( "',c=sn.open();if(null!==c&&c.document.write(l),c||"undefined"==typeof safari)return c;break;case"datauri":case"dataurl":return sn.document.location.href=this.output("datauristring",e);default:return null}}).foo=function(){try{return Vt.apply(this,arguments)}catch(t){var e=t.stack||"";~e.indexOf(" at ")&&(e=e.split(" at ")[1]);var n="Error in function "+e.split("\n")[0].split("<")[0]+": "+t.message;if(!sn.console)throw new Error(n);sn.console.error(n,t),sn.alert&&alert(n)}},(Vt.foo.bar=Vt).foo);switch(e){case"pt":tt=1;break;case"mm":tt=72/25.4;break;case"cm":tt=72/2.54;break;case"in":tt=72;break;case"px":tt=1==Wt("px_scaling")?.75:96/72;break;case"pc":case"em":tt=12;break;case"ex":tt=6;break;default:throw new Error("Invalid unit: "+e)}F(),S();var me=h.__private__.getPageInfo=h.getPageInfo=function(t){if(isNaN(t)||t%1!=0)throw new Error("Invalid argument passed to jsPDF.getPageInfo");return{objId:Lt[t].objId,pageNumber:t,pageContext:Lt[t]}},be=h.__private__.getPageInfoByObjId=function(t){if(isNaN(t)||t%1!=0)throw new Error("Invalid argument passed to jsPDF.getPageInfoByObjId");for(var e in Lt)if(Lt[e].objId===t)break;return me(e)},ve=h.__private__.getCurrentPageInfo=h.getCurrentPageInfo=function(){return{objId:Lt[I].objId,pageNumber:I,pageContext:Lt[I]}};h.addPage=function(){return zt.apply(this,arguments),this},h.setPage=function(){return oe.apply(this,arguments),z.call(this,R[I]),this},h.insertPage=function(t){return this.addPage(),this.movePage(I,t),this},h.movePage=function(t,e){var n,r;if(e":")"),Y=parseFloat(o[Q][1]),J=parseFloat(o[Q][2]);break;case 0:X=(g?"<":"(")+o[Q]+(g?">":")"),Y=Te(e),J=qe(n)}void 0!==q&&void 0!==q[Q]&&(Z=q[Q]+" Tw\n"),0===Q?t.push(Z+$(Y,J,f)+X):0==K?t.push(Z+X):1==K&&t.push(Z+$(Y,J,f)+X)}t=0==K?t.join(" Tj\nT* "):t.join(" Tj\n"),t+=" Tj\n";var tt="BT\n/";return tt+=ct+" "+ut+" Tf\n",tt+=at(ut*b)+" TL\n",tt+=He+"\n",tt+=m,tt+=t,st(tt+="ET"),et[ct]=!0,d},h.__private__.lstext=h.lstext=function(t,e,n,r){return this.text(t,e,n,{charSpace:r})};var ye=h.__private__.clip=h.clip=function(t){return st("evenodd"===t?"W*":"W"),this};h.clipEvenOdd=function(){return ye("evenodd")},h.__private__.clip_fixed=h.clip_fixed=function(t){return h.clip(t)},h.__private__.discardPath=h.discardPath=function(){return st("n"),this};var we=h.__private__.isValidStyle=function(t){var e=!1;return-1!==[void 0,null,"S","D","F","DF","FD","f","f*","B","B*","n"].indexOf(t)&&(e=!0),e};h.__private__.setDefaultPathOperation=h.setDefaultPathOperation=function(t){return we(t)&&(l=t),this};var xe=h.__private__.getStyle=h.getStyle=function(t){var e=l;switch(t){case"D":case"S":e="S";break;case"F":e="f";break;case"FD":case"DF":e="B";break;case"f":case"f*":case"B":case"B*":e=t}return e},Ne=h.close=function(){return st("h"),this};h.stroke=function(){return st("S"),this},h.fill=function(t){return Ae("f",t),this},h.fillEvenOdd=function(t){return Ae("f*",t),this},h.fillStroke=function(t){return Ae("B",t),this},h.fillStrokeEvenOdd=function(t){return Ae("B*",t),this};function Le(t,e,n){null===t||rt===nt&&void 0===t||(t=xe(t),e?(n||(n={matrix:It}),n instanceof Ft&&(n={matrix:n}),n.key=e,n||(n=It),_e(n,t)):st(t))}var Ae=function(t,e){"object"===on(e)?_e(e,t):st(t)},_e=function(t,e){var n=vt[t.key],r=bt[n];if(r instanceof h.ShadingPattern)st("q"),st(Se(e)),r.gState&&h.setGState(r.gState),st(t.matrix.toString()+" cm"),st("/"+n+" sh"),st("Q");else if(r instanceof h.TilingPattern){var i=new Ft(1,0,0,-1,0,rn());t.matrix&&(i=i.multiply(t.matrix||It),n=r.createClone(t.key,t.boundingBox,t.xStep,t.yStep,i).id),st("q"),st("/Pattern cs"),st("/"+n+" scn"),r.gState&&h.setGState(r.gState),st(e),st("Q")}},Se=function(t){switch(t){case"f":case"F":return"W n";case"f*":return"W* n";case"B":return"W S";case"B*":return"W* S";case"S":return"W S";case"n":return"W n"}},Pe=h.moveTo=function(t,e){return st(at(ot(t))+" "+at(w(e))+" m"),this},ke=h.lineTo=function(t,e){return st(at(ot(t))+" "+at(w(e))+" l"),this},Fe=h.curveTo=function(t,e,n,r,i,a){return st([at(ot(t)),at(w(e)),at(ot(n)),at(w(r)),at(ot(i)),at(w(a)),"c"].join(" ")),this};h.__private__.line=h.line=function(t,e,n,r,i){if(isNaN(t)||isNaN(e)||isNaN(n)||isNaN(r)||!we(i))throw new Error("Invalid arguments passed to jsPDF.line");return rt===m?this.lines([[n-t,r-e]],t,e,[1,1],i||"S"):this.lines([[n-t,r-e]],t,e,[1,1]).stroke()},h.__private__.lines=h.lines=function(t,e,n,r,i,a,o,s){var u,l,c,h,f,d,p,g,m,b,v,y;if("number"==typeof t&&(y=n,n=e,e=t,t=y),r=r||[1,1],a=a||!1,isNaN(e)||isNaN(n)||!Array.isArray(t)||!Array.isArray(r)||!we(i)||"boolean"!=typeof a)throw new Error("Invalid arguments passed to jsPDF.lines");for(Pe(e,n),u=r[0],l=r[1],h=t.length,b=e,v=n,c=0;c"}function V(t){var r,e,n,i,a,o=String,s="length",u="charCodeAt",l="slice",c="replace";for(t[l](-2),t=t[l](0,-2)[c](/\s/g,"")[c]("z","!!!!!"),n=[],i=0,a=(t+=r="uuuuu"[l](t[s]%5||5))[s];i>24,255&e>>16,255&e>>8,255&e);return function(t,e){for(var n=r[s];0")&&(t=t.substr(0,t.indexOf(">"))),t.length%2&&(t+="0"),!1===e.test(t))return"";for(var n="",r=0;r>8&255,e>>16&255,e>>24&255]),t.byteLength+2),t=r.reduce(function(t,e){return t+String.fromCharCode(e)},"")}function J(t,e,n,r){var i=5,a=m;switch(r){case P.image_compression.FAST:i=3,a=g;break;case P.image_compression.MEDIUM:i=6,a=b;break;case P.image_compression.SLOW:i=9,a=v}t=p(t,e,n,a);var o=new Uint8Array(d(i)),s=U.API.adler32cs.fromBuffer(t.buffer),u=new Deflater(i),l=u.append(t),c=u.flush(),h=o.length+l.length+c.length,f=new Uint8Array(h+4);return f.set(o),f.set(l,o.length),f.set(c,o.length+l.length),f[h++]=s>>>24&255,f[h++]=s>>>16&255,f[h++]=s>>>8&255,f[h++]=255&s,P.__addimage__.arrayBufferToBinaryString(f)}function X(t){var e=Array.apply([],t);return e.unshift(0),e}function K(t,e,n,r){for(var i=[],a=0,o=t.length,s=0;a!==o&&s+e[a]r&&(i.push(t.slice(u,a)),s=0,u=a),s+=e[a],a++;return u!==a&&i.push(t.slice(u,a)),i}function Z(t,e,n){n||(n={});var r,i,a,o,s,u,l,c=[],h=[c],f=n.textIndent||0,d=0,p=0,g=t.split(" "),m=A.apply(this,[" ",n])[0];if(u=-1===n.lineIndent?g[0].length+2:n.lineIndent||0){var b=Array(u).join(" "),v=[];g.map(function(t){1<(t=t.split(/\s*\n/)).length?v=v.concat(t.map(function(t,e){return(e&&t.length?"\n":"")+t})):v.push(t[0])}),g=v,u=_.apply(this,[b,n])}for(a=0,o=g.length;a',e=unescape(encodeURIComponent('')),n=unescape(encodeURIComponent(t)),r=unescape(encodeURIComponent(this.internal.__metadata__.metadata)),i=unescape(encodeURIComponent("")),a=unescape(encodeURIComponent("")),o=n.length+r.length+i.length+e.length+a.length;this.internal.__metadata__.metadata_object_number=this.internal.newObject(),this.internal.write("<< /Type /Metadata /Subtype /XML /Length "+o+" >>"),this.internal.write("stream"),this.internal.write(e+n+r+i+a),this.internal.write("endstream"),this.internal.write("endobj")}function tt(){this.internal.__metadata__.metadata_object_number&&this.internal.write("/Metadata "+this.internal.__metadata__.metadata_object_number+" 0 R")}function et(){return void 0===this.internal.vFS&&(this.internal.vFS={}),!0}function nt(x){var t=0;if(71!==x[t++]||73!==x[t++]||70!==x[t++]||56!==x[t++]||56!=(x[t++]+1&253)||97!==x[t++])throw new Error("Invalid GIF 87a/89a header.");var N=x[t++]|x[t++]<<8,e=x[t++]|x[t++]<<8,n=x[t++],r=n>>7,i=1<<1+(7&n);x[t++];x[t++];var a=null,o=null;r&&(a=t,t+=3*(o=i));var s=!0,u=[],l=0,c=null,h=0,f=null;for(this.width=N,this.height=e;s&&t>2&7,t++;break;case 254:for(;;){if(!(0<=(P=x[t++])))throw Error("Invalid block size");if(0===P)break;t+=P}break;default:throw new Error("Unknown graphic control label: 0x"+x[t-1].toString(16))}break;case 44:var p=x[t++]|x[t++]<<8,g=x[t++]|x[t++]<<8,m=x[t++]|x[t++]<<8,b=x[t++]|x[t++]<<8,v=x[t++],y=v>>6&1,w=1<<1+(7&v),L=a,A=o,_=!1;if(v>>7){_=!0;L=t,t+=3*(A=w)}var S=t;for(t++;;){var P;if(!(0<=(P=x[t++])))throw Error("Invalid block size");if(0===P)break;t+=P}u.push({x:p,y:g,width:m,height:b,has_local_palette:_,palette_offset:L,palette_size:A,data_offset:S,data_length:t-S,transparent_index:c,interlaced:!!y,delay:l,disposal:h});break;case 59:s=!1;break;default:throw new Error("Unknown gif block: 0x"+x[t-1].toString(16))}this.numFrames=function(){return u.length},this.loopCount=function(){return f},this.frameInfo=function(t){if(t<0||t>=u.length)throw new Error("Frame index out of range.");return u[t]},this.decodeAndBlitFrameBGRA=function(t,e){var n=this.frameInfo(t),r=n.width*n.height,i=new Uint8Array(r);rt(x,n.data_offset,i,r);var a=n.palette_offset,o=n.transparent_index;null===o&&(o=256);var s=n.width,u=N-s,l=s,c=4*(n.y*N+n.x),h=4*((n.y+n.height)*N+n.x),f=c,d=4*u;!0===n.interlaced&&(d+=4*N*7);for(var p=8,g=0,m=i.length;g>=1)),b===o)f+=4;else{var v=x[a+3*b],y=x[a+3*b+1],w=x[a+3*b+2];e[f++]=w,e[f++]=y,e[f++]=v,e[f++]=255}--l}},this.decodeAndBlitFrameRGBA=function(t,e){var n=this.frameInfo(t),r=n.width*n.height,i=new Uint8Array(r);rt(x,n.data_offset,i,r);var a=n.palette_offset,o=n.transparent_index;null===o&&(o=256);var s=n.width,u=N-s,l=s,c=4*(n.y*N+n.x),h=4*((n.y+n.height)*N+n.x),f=c,d=4*u;!0===n.interlaced&&(d+=4*N*7);for(var p=8,g=0,m=i.length;g>=1)),b===o)f+=4;else{var v=x[a+3*b],y=x[a+3*b+1],w=x[a+3*b+2];e[f++]=v,e[f++]=y,e[f++]=w,e[f++]=255}--l}}}function rt(t,e,n,r){for(var i=t[e++],a=1<>=u,c-=u,m!=a){if(m==o)break;for(var b=m>8,++v;var w=y;if(r>=8;null!==g&&s<4096&&(p[s++]=g<<8|w,l+1<=s&&u<12&&(++u,l=l<<1|1)),g=m}else s=1+o,l=(1<<(u=i+1))-1,g=null}return f!==r&&console.log("Warning, gif stream shorter than expected."),n} +/** + * @license + * Copyright (c) 2016 Alexander Weidt, + * https://github.com/BiggA94 + * + * Licensed under the MIT License. http://opensource.org/licenses/mit-license + */ +!function(t,e){function A(t){return t.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")}function b(t){return t.replace(/\\\\/g,"\\").replace(/\\\(/g,"(").replace(/\\\)/g,")")}function _(t){return t.toFixed(2)}function s(t){return t.toFixed(5)}var h,n=t.API,r=1;n.__acroform__={};function i(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t}function v(t){return t*r}function y(t){return t/r}function u(t){var e=new O,n=J.internal.getHeight(t)||0,r=J.internal.getWidth(t)||0;return e.BBox=[0,0,Number(_(r)),Number(_(n))],e}function f(t){if(t.appearanceStreamContent)return t.appearanceStreamContent;if(t.V||t.DV){var e=[],n=t.V||t.DV,r=L(t,n),i=h.internal.getFont(t.fontName,t.fontStyle).id;e.push("/Tx BMC"),e.push("q"),e.push("BT"),e.push(h.__private__.encodeColorString(t.color)),e.push("/"+i+" "+_(r.fontSize)+" Tf"),e.push("1 0 0 1 0 0 Tm"),e.push(r.text),e.push("ET"),e.push("Q"),e.push("EMC");var a=new u(t);return a.stream=e.join("\n"),a}}function a(){h.internal.acroformPlugin.acroFormDictionaryRoot.objId=void 0;var t=h.internal.acroformPlugin.acroFormDictionaryRoot.Fields;for(var e in t)if(t.hasOwnProperty(e)){var n=t[e];n.objId=void 0,n.hasAnnotation&&k.call(h,n)}}function o(){if(void 0===h.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("putCatalogCallback: Root missing.");h.internal.write("/AcroForm "+h.internal.acroformPlugin.acroFormDictionaryRoot.objId+" 0 R")}function l(){h.internal.events.unsubscribe(h.internal.acroformPlugin.acroFormDictionaryRoot._eventID),delete h.internal.acroformPlugin.acroFormDictionaryRoot._eventID,h.internal.acroformPlugin.printedOut=!0}function c(t){var e=!t;for(var n in t||(h.internal.newObjectDeferredBegin(h.internal.acroformPlugin.acroFormDictionaryRoot.objId,!0),h.internal.acroformPlugin.acroFormDictionaryRoot.putStream()),t=t||h.internal.acroformPlugin.acroFormDictionaryRoot.Kids)if(t.hasOwnProperty(n)){var r=t[n],i=[],a=r.Rect;if(r.Rect&&(r.Rect=m.call(this,r.Rect)),h.internal.newObjectDeferredBegin(r.objId,!0),r.DA=J.createDefaultAppearanceStream(r),"object"===on(r)&&"function"==typeof r.getKeyValueListForStream&&(i=r.getKeyValueListForStream()),r.Rect=a,r.hasAppearanceStream&&!r.appearanceStreamContent){var o=f.call(this,r);i.push({key:"AP",value:"<>"}),h.internal.acroformPlugin.xForms.push(o)}if(r.appearanceStreamContent){var s="";for(var u in r.appearanceStreamContent)if(r.appearanceStreamContent.hasOwnProperty(u)){var l=r.appearanceStreamContent[u];if(s+="/"+u+" ",s+="<<",1<=Object.keys(l).length||Array.isArray(l)){for(var n in l)if(l.hasOwnProperty(n)){var c=l[n];"function"==typeof c&&(c=c.call(this,r)),s+="/"+n+" "+c+" ",0<=h.internal.acroformPlugin.xForms.indexOf(c)||h.internal.acroformPlugin.xForms.push(c)}}else"function"==typeof(c=l)&&(c=c.call(this,r)),s+="/"+n+" "+c,0<=h.internal.acroformPlugin.xForms.indexOf(c)||h.internal.acroformPlugin.xForms.push(c);s+=">>"}i.push({key:"AP",value:"<<\n"+s+">>"})}h.internal.putStream({additionalKeyValues:i}),h.internal.out("endobj")}e&&F.call(this,h.internal.acroformPlugin.xForms)}var d=n.__acroform__.setBit=function(t,e){if(t=t||0,e=e||0,isNaN(t)||isNaN(e))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBit");return t|=1<=a.length-1;if(w&&!x){m+=" ";continue}if(w||x){if(x)g=y;else if(i.multiline&&o<(h+2)*(b+2)+2)continue t}else{if(!i.multiline)continue t;if(o<(h+2)*(b+2)+2)continue t;g=y}for(var N="",L=p;L<=g;L++)N+=a[L]+" ";switch(N=" "==N.substr(N.length-1)?N.substr(0,N.length-1):N,c=S(N,i,r).width,i.textAlign){case"right":l=s-c-2;break;case"center":l=(s-c)/2;break;case"left":default:l=2}t+=_(l)+" "+_(d)+" Td\n",t+="("+A(N)+") Tj\n",t+=-_(l)+" 0 Td\n",d=-(r+2),c=0,p=g+1,b++,m=""}else;break}return n.text=t,n.fontSize=r,n},S=function(t,e,n){var r=h.internal.getFont(e.fontName,e.fontStyle),i=h.getStringUnitWidth(t,{font:r,fontSize:parseFloat(n),charSpace:0})*parseFloat(n);return{height:h.getStringUnitWidth("3",{font:r,fontSize:parseFloat(n),charSpace:0})*parseFloat(n)*1.5,width:i}},P={fields:[],xForms:[],acroFormDictionaryRoot:null,printedOut:!1,internal:null,isInitialized:!1},k=function(t){var e={type:"reference",object:t};void 0===h.internal.getPageInfo(t.page).pageContext.annotations.find(function(t){return t.type===e.type&&t.object===e.object})&&h.internal.getPageInfo(t.page).pageContext.annotations.push(e)},F=function(t){for(var e in t)if(t.hasOwnProperty(e)){var n=e,r=t[e];h.internal.newObjectDeferredBegin(r&&r.objId,!0),"object"===on(r)&&"function"==typeof r.putStream&&r.putStream(),delete t[n]}},C=function(){if(void 0!==this.internal&&(void 0===this.internal.acroformPlugin||!1===this.internal.acroformPlugin.isInitialized)){if(h=this,M.FieldNum=0,this.internal.acroformPlugin=JSON.parse(JSON.stringify(P)),this.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("Exception while creating AcroformDictionary");r=h.internal.scaleFactor,h.internal.acroformPlugin.acroFormDictionaryRoot=new E,h.internal.acroformPlugin.acroFormDictionaryRoot._eventID=h.internal.events.subscribe("postPutResources",l),h.internal.events.subscribe("buildDocument",a),h.internal.events.subscribe("putCatalog",o),h.internal.events.subscribe("postPutPages",c),h.internal.acroformPlugin.isInitialized=!0}},I=n.__acroform__.arrayToPdfArray=function(t){if(Array.isArray(t)){for(var e="[",n=0;n>"),e.join("\n")}},set:function(t){"object"===on(t)&&(n=t)}}),Object.defineProperty(this,"caption",{enumerable:!0,configurable:!0,get:function(){return n.CA||""},set:function(t){"string"==typeof t&&(n.CA=t)}}),Object.defineProperty(this,"AS",{enumerable:!1,configurable:!1,get:function(){return e},set:function(t){e=t}}),Object.defineProperty(this,"appearanceState",{enumerable:!0,configurable:!0,get:function(){return e.substr(1,e.length-1)},set:function(t){e="/"+t}})};i(U,M);function z(){U.call(this),this.pushButton=!0}i(z,U);function H(){U.call(this),this.radio=!0,this.pushButton=!1;var e=[];Object.defineProperty(this,"Kids",{enumerable:!0,configurable:!1,get:function(){return e},set:function(t){e=void 0!==t?t:[]}})}i(H,U);var W=function(){var e,n;M.call(this),Object.defineProperty(this,"Parent",{enumerable:!1,configurable:!1,get:function(){return e},set:function(t){e=t}}),Object.defineProperty(this,"optionName",{enumerable:!1,configurable:!0,get:function(){return n},set:function(t){n=t}});var r,i={};Object.defineProperty(this,"MK",{enumerable:!1,configurable:!1,get:function(){var t,e=[];for(t in e.push("<<"),i)e.push("/"+t+" ("+i[t]+")");return e.push(">>"),e.join("\n")},set:function(t){"object"===on(t)&&(i=t)}}),Object.defineProperty(this,"caption",{enumerable:!0,configurable:!0,get:function(){return i.CA||""},set:function(t){"string"==typeof t&&(i.CA=t)}}),Object.defineProperty(this,"AS",{enumerable:!1,configurable:!1,get:function(){return r},set:function(t){r=t}}),Object.defineProperty(this,"appearanceState",{enumerable:!0,configurable:!0,get:function(){return r.substr(1,r.length-1)},set:function(t){r="/"+t}}),this.caption="l",this.appearanceState="Off",this._AppearanceType=J.RadioButton.Circle,this.appearanceStreamContent=this._AppearanceType.createAppearanceStream(this.optionName)};i(W,M),H.prototype.setAppearance=function(t){if(!("createAppearanceStream"in t&&"getCA"in t))throw new Error("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");for(var e in this.Kids)if(this.Kids.hasOwnProperty(e)){var n=this.Kids[e];n.appearanceStreamContent=t.createAppearanceStream(n.optionName),n.caption=t.getCA()}},H.prototype.createOption=function(t){var e=new W;return e.Parent=this,e.optionName=t,this.Kids.push(e),X.call(this,e),e};function V(){U.call(this),this.fontName="zapfdingbats",this.caption="3",this.appearanceState="On",this.value="On",this.textAlign="center",this.appearanceStreamContent=J.CheckBox.createAppearanceStream()}i(V,U);var G=function(){M.call(this),this.FT="/Tx",Object.defineProperty(this,"multiline",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,13))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,13):this.Ff=N(this.Ff,13)}}),Object.defineProperty(this,"fileSelect",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,21))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,21):this.Ff=N(this.Ff,21)}}),Object.defineProperty(this,"doNotSpellCheck",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,23))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,23):this.Ff=N(this.Ff,23)}}),Object.defineProperty(this,"doNotScroll",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,24))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,24):this.Ff=N(this.Ff,24)}}),Object.defineProperty(this,"comb",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,25))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,25):this.Ff=N(this.Ff,25)}}),Object.defineProperty(this,"richText",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,26))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,26):this.Ff=N(this.Ff,26)}});var e=null;Object.defineProperty(this,"MaxLen",{enumerable:!0,configurable:!1,get:function(){return e},set:function(t){e=t}}),Object.defineProperty(this,"maxLength",{enumerable:!0,configurable:!0,get:function(){return e},set:function(t){Number.isInteger(t)&&(e=t)}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!0,configurable:!0,get:function(){return this.V||this.DV}})};i(G,M);function Y(){G.call(this),Object.defineProperty(this,"password",{enumerable:!0,configurable:!0,get:function(){return Boolean(w(this.Ff,14))},set:function(t){!0===Boolean(t)?this.Ff=x(this.Ff,14):this.Ff=N(this.Ff,14)}}),this.password=!0}i(Y,G);var J={CheckBox:{createAppearanceStream:function(){return{N:{On:J.CheckBox.YesNormal},D:{On:J.CheckBox.YesPushDown,Off:J.CheckBox.OffPushDown}}},YesPushDown:function(t){var e=new u(t),n=[],r=h.internal.getFont(t.fontName,t.fontStyle).id,i=h.__private__.encodeColorString(t.color),a=L(t,t.caption);return n.push("0.749023 g"),n.push("0 0 "+_(J.internal.getWidth(t))+" "+_(J.internal.getHeight(t))+" re"),n.push("f"),n.push("BMC"),n.push("q"),n.push("0 0 1 rg"),n.push("/"+r+" "+_(a.fontSize)+" Tf "+i),n.push("BT"),n.push(a.text),n.push("ET"),n.push("Q"),n.push("EMC"),e.stream=n.join("\n"),e},YesNormal:function(t){var e=new u(t),n=h.internal.getFont(t.fontName,t.fontStyle).id,r=h.__private__.encodeColorString(t.color),i=[],a=J.internal.getHeight(t),o=J.internal.getWidth(t),s=L(t,t.caption);return i.push("1 g"),i.push("0 0 "+_(o)+" "+_(a)+" re"),i.push("f"),i.push("q"),i.push("0 0 1 rg"),i.push("0 0 "+_(o-1)+" "+_(a-1)+" re"),i.push("W"),i.push("n"),i.push("0 g"),i.push("BT"),i.push("/"+n+" "+_(s.fontSize)+" Tf "+r),i.push(s.text),i.push("ET"),i.push("Q"),e.stream=i.join("\n"),e},OffPushDown:function(t){var e=new u(t),n=[];return n.push("0.749023 g"),n.push("0 0 "+_(J.internal.getWidth(t))+" "+_(J.internal.getHeight(t))+" re"),n.push("f"),e.stream=n.join("\n"),e}},RadioButton:{Circle:{createAppearanceStream:function(t){var e={D:{Off:J.RadioButton.Circle.OffPushDown},N:{}};return e.N[t]=J.RadioButton.Circle.YesNormal,e.D[t]=J.RadioButton.Circle.YesPushDown,e},getCA:function(){return"l"},YesNormal:function(t){var e=new u(t),n=[],r=J.internal.getWidth(t)<=J.internal.getHeight(t)?J.internal.getWidth(t)/4:J.internal.getHeight(t)/4;r=Number((.9*r).toFixed(5));var i=J.internal.Bezier_C,a=Number((r*i).toFixed(5));return n.push("q"),n.push("1 0 0 1 "+s(J.internal.getWidth(t)/2)+" "+s(J.internal.getHeight(t)/2)+" cm"),n.push(r+" 0 m"),n.push(r+" "+a+" "+a+" "+r+" 0 "+r+" c"),n.push("-"+a+" "+r+" -"+r+" "+a+" -"+r+" 0 c"),n.push("-"+r+" -"+a+" -"+a+" -"+r+" 0 -"+r+" c"),n.push(a+" -"+r+" "+r+" -"+a+" "+r+" 0 c"),n.push("f"),n.push("Q"),e.stream=n.join("\n"),e},YesPushDown:function(t){var e=new u(t),n=[],r=J.internal.getWidth(t)<=J.internal.getHeight(t)?J.internal.getWidth(t)/4:J.internal.getHeight(t)/4,i=(r=Number((.9*r).toFixed(5)),Number((2*r).toFixed(5))),a=Number((i*J.internal.Bezier_C).toFixed(5)),o=Number((r*J.internal.Bezier_C).toFixed(5));return n.push("0.749023 g"),n.push("q"),n.push("1 0 0 1 "+s(J.internal.getWidth(t)/2)+" "+s(J.internal.getHeight(t)/2)+" cm"),n.push(i+" 0 m"),n.push(i+" "+a+" "+a+" "+i+" 0 "+i+" c"),n.push("-"+a+" "+i+" -"+i+" "+a+" -"+i+" 0 c"),n.push("-"+i+" -"+a+" -"+a+" -"+i+" 0 -"+i+" c"),n.push(a+" -"+i+" "+i+" -"+a+" "+i+" 0 c"),n.push("f"),n.push("Q"),n.push("0 g"),n.push("q"),n.push("1 0 0 1 "+s(J.internal.getWidth(t)/2)+" "+s(J.internal.getHeight(t)/2)+" cm"),n.push(r+" 0 m"),n.push(r+" "+o+" "+o+" "+r+" 0 "+r+" c"),n.push("-"+o+" "+r+" -"+r+" "+o+" -"+r+" 0 c"),n.push("-"+r+" -"+o+" -"+o+" -"+r+" 0 -"+r+" c"),n.push(o+" -"+r+" "+r+" -"+o+" "+r+" 0 c"),n.push("f"),n.push("Q"),e.stream=n.join("\n"),e},OffPushDown:function(t){var e=new u(t),n=[],r=J.internal.getWidth(t)<=J.internal.getHeight(t)?J.internal.getWidth(t)/4:J.internal.getHeight(t)/4;r=Number((.9*r).toFixed(5));var i=Number((2*r).toFixed(5)),a=Number((i*J.internal.Bezier_C).toFixed(5));return n.push("0.749023 g"),n.push("q"),n.push("1 0 0 1 "+s(J.internal.getWidth(t)/2)+" "+s(J.internal.getHeight(t)/2)+" cm"),n.push(i+" 0 m"),n.push(i+" "+a+" "+a+" "+i+" 0 "+i+" c"),n.push("-"+a+" "+i+" -"+i+" "+a+" -"+i+" 0 c"),n.push("-"+i+" -"+a+" -"+a+" -"+i+" 0 -"+i+" c"),n.push(a+" -"+i+" "+i+" -"+a+" "+i+" 0 c"),n.push("f"),n.push("Q"),e.stream=n.join("\n"),e}},Cross:{createAppearanceStream:function(t){var e={D:{Off:J.RadioButton.Cross.OffPushDown},N:{}};return e.N[t]=J.RadioButton.Cross.YesNormal,e.D[t]=J.RadioButton.Cross.YesPushDown,e},getCA:function(){return"8"},YesNormal:function(t){var e=new u(t),n=[],r=J.internal.calculateCross(t);return n.push("q"),n.push("1 1 "+_(J.internal.getWidth(t)-2)+" "+_(J.internal.getHeight(t)-2)+" re"),n.push("W"),n.push("n"),n.push(_(r.x1.x)+" "+_(r.x1.y)+" m"),n.push(_(r.x2.x)+" "+_(r.x2.y)+" l"),n.push(_(r.x4.x)+" "+_(r.x4.y)+" m"),n.push(_(r.x3.x)+" "+_(r.x3.y)+" l"),n.push("s"),n.push("Q"),e.stream=n.join("\n"),e},YesPushDown:function(t){var e=new u(t),n=J.internal.calculateCross(t),r=[];return r.push("0.749023 g"),r.push("0 0 "+_(J.internal.getWidth(t))+" "+_(J.internal.getHeight(t))+" re"),r.push("f"),r.push("q"),r.push("1 1 "+_(J.internal.getWidth(t)-2)+" "+_(J.internal.getHeight(t)-2)+" re"),r.push("W"),r.push("n"),r.push(_(n.x1.x)+" "+_(n.x1.y)+" m"),r.push(_(n.x2.x)+" "+_(n.x2.y)+" l"),r.push(_(n.x4.x)+" "+_(n.x4.y)+" m"),r.push(_(n.x3.x)+" "+_(n.x3.y)+" l"),r.push("s"),r.push("Q"),e.stream=r.join("\n"),e},OffPushDown:function(t){var e=new u(t),n=[];return n.push("0.749023 g"),n.push("0 0 "+_(J.internal.getWidth(t))+" "+_(J.internal.getHeight(t))+" re"),n.push("f"),e.stream=n.join("\n"),e}}},createDefaultAppearanceStream:function(t){var e=h.internal.getFont(t.fontName,t.fontStyle).id,n=h.__private__.encodeColorString(t.color);return"/"+e+" "+t.fontSize+" Tf "+n}};J.internal={Bezier_C:.551915024494,calculateCross:function(t){var e=J.internal.getWidth(t),n=J.internal.getHeight(t),r=Math.min(e,n);return{x1:{x:(e-r)/2,y:(n-r)/2+r},x2:{x:(e-r)/2+r,y:(n-r)/2},x3:{x:(e-r)/2,y:(n-r)/2},x4:{x:(e-r)/2+r,y:(n-r)/2+r}}}},J.internal.getWidth=function(t){var e=0;return"object"===on(t)&&(e=v(t.Rect[2])),e},J.internal.getHeight=function(t){var e=0;return"object"===on(t)&&(e=v(t.Rect[3])),e};var X=n.addField=function(t){if(C.call(this),!(t instanceof M))throw new Error("Invalid argument passed to jsPDF.addField.");return function(t){h.internal.acroformPlugin.printedOut&&(h.internal.acroformPlugin.printedOut=!1,h.internal.acroformPlugin.acroFormDictionaryRoot=null),h.internal.acroformPlugin.acroFormDictionaryRoot||C.call(h),h.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(t)}.call(this,t),t.page=h.internal.getCurrentPageInfo().pageNumber,this};n.addButton=function(t){if(t instanceof U==!1)throw new Error("Invalid argument passed to jsPDF.addButton.");return X.call(this,t)},n.addTextField=function(t){if(t instanceof G==!1)throw new Error("Invalid argument passed to jsPDF.addTextField.");return X.call(this,t)},n.addChoiceField=function(t){if(t instanceof T==!1)throw new Error("Invalid argument passed to jsPDF.addChoiceField.");return X.call(this,t)},"object"==on(e)&&void 0===e.ChoiceField&&void 0===e.ListBox&&void 0===e.ComboBox&&void 0===e.EditBox&&void 0===e.Button&&void 0===e.PushButton&&void 0===e.RadioButton&&void 0===e.CheckBox&&void 0===e.TextField&&void 0===e.PasswordField?(e.ChoiceField=T,e.ListBox=q,e.ComboBox=R,e.EditBox=D,e.Button=U,e.PushButton=z,e.RadioButton=H,e.CheckBox=V,e.TextField=G,e.PasswordField=Y,e.AcroForm={Appearance:J}):console.warn("AcroForm-Classes are not populated into global-namespace, because the class-Names exist already. This avoids conflicts with the already used framework."),n.AcroFormChoiceField=T,n.AcroFormListBox=q,n.AcroFormComboBox=R,n.AcroFormEditBox=D,n.AcroFormButton=U,n.AcroFormPushButton=z,n.AcroFormRadioButton=H,n.AcroFormCheckBox=V,n.AcroFormTextField=G,n.AcroFormPasswordField=Y,n.AcroFormAppearance=J,n.AcroForm={ChoiceField:T,ListBox:q,ComboBox:R,EditBox:D,Button:U,PushButton:z,RadioButton:H,CheckBox:V,TextField:G,PasswordField:Y,Appearance:J},t.AcroForm={ChoiceField:T,ListBox:q,ComboBox:R,EditBox:D,Button:U,PushButton:z,RadioButton:H,CheckBox:V,TextField:G,PasswordField:Y,Appearance:J}}(U,"undefined"!=typeof window&&window||"undefined"!=typeof global&&global), +/** @license + * jsPDF addImage plugin + * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/ + * 2013 Chris Dowling, https://github.com/gingerchris + * 2013 Trinh Ho, https://github.com/ineedfat + * 2013 Edwin Alejandro Perez, https://github.com/eaparango + * 2013 Norah Smith, https://github.com/burnburnrocket + * 2014 Diego Casorran, https://github.com/diegocr + * 2014 James Robb, https://github.com/jamesbrobb + * + * + */ +function(s){var p="addImage_";s.__addimage__={};function h(t){for(var e=this.internal.write,n=this.internal.putStream,r=(0,this.internal.getFilters)();-1!==r.indexOf("FlateEncode");)r.splice(r.indexOf("FlateEncode"),1);t.objectId=this.internal.newObject();var i=[];if(i.push({key:"Type",value:"/XObject"}),i.push({key:"Subtype",value:"/Image"}),i.push({key:"Width",value:t.width}),i.push({key:"Height",value:t.height}),t.colorSpace===v.INDEXED?i.push({key:"ColorSpace",value:"[/Indexed /DeviceRGB "+(t.palette.length/3-1)+" "+("sMask"in t&&void 0!==t.sMask?t.objectId+2:t.objectId+1)+" 0 R]"}):(i.push({key:"ColorSpace",value:"/"+t.colorSpace}),t.colorSpace===v.DEVICE_CMYK&&i.push({key:"Decode",value:"[1 0 1 0 1 0 1 0]"})),i.push({key:"BitsPerComponent",value:t.bitsPerComponent}),"decodeParameters"in t&&void 0!==t.decodeParameters&&i.push({key:"DecodeParms",value:"<<"+t.decodeParameters+">>"}),"transparency"in t&&Array.isArray(t.transparency)){for(var a="",o=0,s=t.transparency.length;o>",h.content=r;var p=h.objId+" 0 R";r="<>";else if(e.options.pageNumber)switch(r="<>",this.internal.write(r))}this.internal.write("]")}}]),t.createAnnotation=function(t){var e=this.internal.getCurrentPageInfo();switch(t.type){case"link":this.link(t.bounds.x,t.bounds.y,t.bounds.w,t.bounds.h,t);break;case"text":case"freetext":e.pageContext.annotations.push(t)}},t.link=function(t,e,n,r,i){this.internal.getCurrentPageInfo().pageContext.annotations.push({x:t,y:e,w:n,h:r,options:i,type:"link"})},t.textWithLink=function(t,e,n,r){var i=this.getTextWidth(t),a=this.internal.getLineHeight()/this.internal.scaleFactor;return this.text(t,e,n,r),n+=.2*a,this.link(e,n-a,i,a,r),i},t.getTextWidth=function(t){var e=this.internal.getFontSize();return this.getStringUnitWidth(t)*e/this.internal.scaleFactor}, +/** + * @license + * Copyright (c) 2017 Aras Abbasi + * + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +function(t){var l={1569:[65152],1570:[65153,65154],1571:[65155,65156],1572:[65157,65158],1573:[65159,65160],1574:[65161,65162,65163,65164],1575:[65165,65166],1576:[65167,65168,65169,65170],1577:[65171,65172],1578:[65173,65174,65175,65176],1579:[65177,65178,65179,65180],1580:[65181,65182,65183,65184],1581:[65185,65186,65187,65188],1582:[65189,65190,65191,65192],1583:[65193,65194],1584:[65195,65196],1585:[65197,65198],1586:[65199,65200],1587:[65201,65202,65203,65204],1588:[65205,65206,65207,65208],1589:[65209,65210,65211,65212],1590:[65213,65214,65215,65216],1591:[65217,65218,65219,65220],1592:[65221,65222,65223,65224],1593:[65225,65226,65227,65228],1594:[65229,65230,65231,65232],1601:[65233,65234,65235,65236],1602:[65237,65238,65239,65240],1603:[65241,65242,65243,65244],1604:[65245,65246,65247,65248],1605:[65249,65250,65251,65252],1606:[65253,65254,65255,65256],1607:[65257,65258,65259,65260],1608:[65261,65262],1609:[65263,65264,64488,64489],1610:[65265,65266,65267,65268],1649:[64336,64337],1655:[64477],1657:[64358,64359,64360,64361],1658:[64350,64351,64352,64353],1659:[64338,64339,64340,64341],1662:[64342,64343,64344,64345],1663:[64354,64355,64356,64357],1664:[64346,64347,64348,64349],1667:[64374,64375,64376,64377],1668:[64370,64371,64372,64373],1670:[64378,64379,64380,64381],1671:[64382,64383,64384,64385],1672:[64392,64393],1676:[64388,64389],1677:[64386,64387],1678:[64390,64391],1681:[64396,64397],1688:[64394,64395],1700:[64362,64363,64364,64365],1702:[64366,64367,64368,64369],1705:[64398,64399,64400,64401],1709:[64467,64468,64469,64470],1711:[64402,64403,64404,64405],1713:[64410,64411,64412,64413],1715:[64406,64407,64408,64409],1722:[64414,64415],1723:[64416,64417,64418,64419],1726:[64426,64427,64428,64429],1728:[64420,64421],1729:[64422,64423,64424,64425],1733:[64480,64481],1734:[64473,64474],1735:[64471,64472],1736:[64475,64476],1737:[64482,64483],1739:[64478,64479],1740:[64508,64509,64510,64511],1744:[64484,64485,64486,64487],1746:[64430,64431],1747:[64432,64433]},a={65247:{65154:65269,65156:65271,65160:65273,65166:65275},65248:{65154:65270,65156:65272,65160:65274,65166:65276},65165:{65247:{65248:{65258:65010}}},1617:{1612:64606,1613:64607,1614:64608,1615:64609,1616:64610}},e={1612:64606,1613:64607,1614:64608,1615:64609,1616:64610},n=[1570,1571,1573,1575];t.__arabicParser__={};var r=t.__arabicParser__.isInArabicSubstitutionA=function(t){return void 0!==l[t.charCodeAt(0)]},c=t.__arabicParser__.isArabicLetter=function(t){return"string"==typeof t&&/^[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]+$/.test(t)},i=t.__arabicParser__.isArabicEndLetter=function(t){return c(t)&&r(t)&&l[t.charCodeAt(0)].length<=2},o=t.__arabicParser__.isArabicAlfLetter=function(t){return c(t)&&0<=n.indexOf(t.charCodeAt(0))};t.__arabicParser__.arabicLetterHasIsolatedForm=function(t){return c(t)&&r(t)&&1<=l[t.charCodeAt(0)].length};var s=t.__arabicParser__.arabicLetterHasFinalForm=function(t){return c(t)&&r(t)&&2<=l[t.charCodeAt(0)].length};t.__arabicParser__.arabicLetterHasInitialForm=function(t){return c(t)&&r(t)&&3<=l[t.charCodeAt(0)].length};var u=t.__arabicParser__.arabicLetterHasMedialForm=function(t){return c(t)&&r(t)&&4==l[t.charCodeAt(0)].length},h=t.__arabicParser__.resolveLigatures=function(t){var e=0,n=a,r="",i=0;for(e=0;e>"),this.internal.out("endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.out("/OpenAction "+e+" 0 R")})}return this}, +/** + * @license + * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv + * + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +e=U.API,H.prototype.getContext=function(t,e){var n;if("2d"!==(t=t||"2d"))return null;for(n in e)this.pdf.context2d.hasOwnProperty(n)&&(this.pdf.context2d[n]=e[n]);return(this.pdf.context2d._canvas=this).pdf.context2d},H.prototype.toDataURL=function(){throw new Error("toDataURL is not implemented.")},e.events.push(["initialized",function(){this.canvas=new H,this.canvas.pdf=this}]), +/** + * @license + * ==================================================================== + * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com + * 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br + * 2013 Lee Driscoll, https://github.com/lsdriscoll + * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria + * 2014 James Hall, james@parall.ax + * 2014 Diego Casorran, https://github.com/diegocr + * + * + * ==================================================================== + */ +function(t){function S(){void 0===this.internal.__cell__&&(this.internal.__cell__={},this.internal.__cell__.padding=3,this.internal.__cell__.headerFunction=void 0,this.internal.__cell__.margins=Object.assign({},P),this.internal.__cell__.margins.width=this.getPageWidth(),k.call(this))}var P={left:0,top:0,bottom:0,right:0},o=!1,k=function(){this.internal.__cell__.lastCell=new F,this.internal.__cell__.pages=1},F=function(){var e=arguments[0];Object.defineProperty(this,"x",{enumerable:!0,get:function(){return e},set:function(t){e=t}});var n=arguments[1];Object.defineProperty(this,"y",{enumerable:!0,get:function(){return n},set:function(t){n=t}});var r=arguments[2];Object.defineProperty(this,"width",{enumerable:!0,get:function(){return r},set:function(t){r=t}});var i=arguments[3];Object.defineProperty(this,"height",{enumerable:!0,get:function(){return i},set:function(t){i=t}});var a=arguments[4];Object.defineProperty(this,"text",{enumerable:!0,get:function(){return a},set:function(t){a=t}});var o=arguments[5];Object.defineProperty(this,"lineNumber",{enumerable:!0,get:function(){return o},set:function(t){o=t}});var s=arguments[6];return Object.defineProperty(this,"align",{enumerable:!0,get:function(){return s},set:function(t){s=t}}),this};F.prototype.clone=function(){return new F(this.x,this.y,this.width,this.height,this.text,this.lineNumber,this.align)},F.prototype.toArray=function(){return[this.x,this.y,this.width,this.height,this.text,this.lineNumber,this.align]},t.setHeaderFunction=function(t){return S.call(this),this.internal.__cell__.headerFunction="function"==typeof t?t:void 0,this},t.getTextDimensions=function(t,e){S.call(this);var n=(e=e||{}).fontSize||this.getFontSize(),r=e.font||this.getFont(),i=e.scaleFactor||this.internal.scaleFactor,a=0,o=0,s=0;if(!Array.isArray(t)&&"string"!=typeof t)throw new Error("getTextDimensions expects text-parameter to be of type String or an Array of Strings.");t=Array.isArray(t)?t:[t];for(var u=0;uthis.getPageHeight()?(this.cellAddPage(),t.y=r.top,a&&i&&(this.printHeaderRow(t.lineNumber,!0),t.y+=i[0].height)):t.y=e.y+e.height||t.y),void 0!==t.text[0]&&(this.rect(t.x,t.y,t.width,t.height,!0===o?"FD":void 0),"right"===t.align?this.text(t.text,t.x+t.width-n,t.y+n,{align:"right",baseline:"top"}):"center"===t.align?this.text(t.text,t.x+t.width/2,t.y+n,{align:"center",baseline:"top",maxWidth:t.width-n-n}):this.text(t.text,t.x+n,t.y+n,{align:"left",baseline:"top",maxWidth:t.width-n-n})),this.internal.__cell__.lastCell=t,this};t.table=function(e,n,t,r,i){if(S.call(this),!t)throw new Error("No data for PDF table.");var a,o,s,u,l=[],c=[],h=[],f={},d={},p=[],g=[],m=(i=i||{}).autoSize||!1,b=!1!==i.printHeaders,v=i.css&&void 0!==i.css["font-size"]?16*i.css["font-size"]:i.fontSize||12,y=i.margins||Object.assign({width:this.getPageWidth()},P),w="number"==typeof i.padding?i.padding:3,x=i.headerBackgroundColor||"#c8c8c8";if(k.call(this),this.internal.__cell__.printHeaders=b,this.internal.__cell__.margins=y,this.internal.__cell__.table_font_size=v,this.internal.__cell__.padding=w,this.internal.__cell__.headerBackgroundColor=x,this.setFontSize(v),null==r)h=(c=l=Object.keys(t[0])).map(function(){return"left"});else if(Array.isArray(r)&&"object"===on(r[0]))for(l=r.map(function(t){return t.name}),c=r.map(function(t){return t.prompt||t.name||""}),h=l.map(function(t){return t.align||"left"}),a=0;a=2*Math.PI&&(r=0,i=2*Math.PI),this.path.push({type:"arc",x:t,y:e,radius:n,startAngle:r,endAngle:i,counterclockwise:a})},e.prototype.arcTo=function(t,e,n,r,i){throw new Error("arcTo not implemented.")},e.prototype.rect=function(t,e,n,r){if(isNaN(t)||isNaN(e)||isNaN(n)||isNaN(r))throw console.error("jsPDF.context2d.rect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.rect");this.moveTo(t,e),this.lineTo(t+n,e),this.lineTo(t+n,e+r),this.lineTo(t,e+r),this.lineTo(t,e),this.lineTo(t+n,e),this.lineTo(t,e)},e.prototype.fillRect=function(t,e,n,r){if(isNaN(t)||isNaN(e)||isNaN(n)||isNaN(r))throw console.error("jsPDF.context2d.fillRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.fillRect");if(!x.call(this)){var i={};"butt"!==this.lineCap&&(i.lineCap=this.lineCap,this.lineCap="butt"),"miter"!==this.lineJoin&&(i.lineJoin=this.lineJoin,this.lineJoin="miter"),this.beginPath(),this.rect(t,e,n,r),this.fill(),i.hasOwnProperty("lineCap")&&(this.lineCap=i.lineCap),i.hasOwnProperty("lineJoin")&&(this.lineJoin=i.lineJoin)}},e.prototype.strokeRect=function(t,e,n,r){if(isNaN(t)||isNaN(e)||isNaN(n)||isNaN(r))throw console.error("jsPDF.context2d.strokeRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.strokeRect");N.call(this)||(this.beginPath(),this.rect(t,e,n,r),this.stroke())},e.prototype.clearRect=function(t,e,n,r){if(isNaN(t)||isNaN(e)||isNaN(n)||isNaN(r))throw console.error("jsPDF.context2d.clearRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.clearRect");this.ignoreClearRect||(this.fillStyle="#ffffff",this.fillRect(t,e,n,r))},e.prototype.save=function(t){t="boolean"!=typeof t||t;for(var e=this.pdf.internal.getCurrentPageInfo().pageNumber,n=0;n",i.push("/ASCIIHexDecode");break;case"FlateEncode":case"/FlateEncode":r=Y(r),i.push("/FlateDecode");break;default:throw new Error('The filter: "'+e[n]+'" is not implemented')}return{data:r,reverseChain:i.reverse().join(" ")}},( +/** + * jsPDF fileloading PlugIn + * Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com) + * + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +n=U.API).loadFile=function(t,e,n){e=!1!==e,n="function"==typeof n?n:function(){};var r=void 0;try{r=function(t,e,n){function r(t){var e=t.length,n=[],r=String.fromCharCode;for(a=0;a>"),this.internal.out("endobj"),i=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /JavaScript"),this.internal.out("/JS ("+o+")"),this.internal.out(">>"),this.internal.out("endobj")}),this.internal.events.subscribe("putCatalog",function(){void 0!==r&&void 0!==i&&this.internal.out("/Names <>")}),this},( +/** + * @license + * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv + * + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + */ +s=U.API).events.push(["postPutResources",function(){var t=this,e=/^(\d+) 0 obj$/;if(0> endobj")}var h=t.internal.newObject();for(t.internal.write("<< /Names [ "),r=0;r>","endobj"),f=t.internal.newObject(),t.internal.write("<< /Dests "+h+" 0 R"),t.internal.write(">>","endobj")}}]),s.events.push(["putCatalog",function(){0> \r\nendobj\r\n"},s.outline.count_r=function(t,e){for(var n=0;n>1)<<6,e|=0,[120,255&(e+=31-e%31)]},p=function(t,e,n,r){for(var i,a,o,s=t.length/e,u=new Uint8Array(t.length+s),l=y(),c=0;c>>1)&255;return a},v=function(t,e,n){var r,i,a,o,s=[],u=t.length;s[0]=4;for(var l=0;l>>x&255,x+=o.bits;d[b]=m>>>x&255}}if(16===o.bits){f=(h=new Uint32Array(o.decodePixels().buffer)).length,p=new Uint8Array(f*(32/o.pixelBitlength)*o.colors),d=new Uint8Array(f*(32/o.pixelBitlength)),g=1>>0&255,g&&(p[v++]=m>>>16&255,m=h[b++],p[v++]=m>>>0&255),d[L++]=m>>>16&255;a=8}!function(t){return t!==P.image_compression.NONE&&F()}(r)?(t=p,c=d,y=void 0):(t=J(p,o.width*o.colors,o.colors,r),c=J(d,o.width,1,r))}if(3===o.colorType&&(i=this.color_spaces.INDEXED,l=o.palette,o.transparency.indexed)){var A=o.transparency.indexed,_=0;for(b=0,f=A.length;b>")}),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=n,this},U.API.addMetadata=function(t,e){return void 0===this.internal.__metadata__&&(this.internal.__metadata__={metadata:t,namespaceuri:e||"http://jspdf.default.namespaceuri/"},this.internal.events.subscribe("putCatalog",tt),this.internal.events.subscribe("postPutResources",Q)),this},function(p){function g(t){var e,n,r,i,a,o,s;for(a="/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000>\nendcodespacerange",r=[],o=0,s=(n=Object.keys(t).sort(function(t,e){return t-e})).length;o<"+i+">"));return r.length&&(a+="\n"+r.length+" beginbfchar\n"+r.join("\n")+"\nendbfchar\n"),a+="endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"}var t=p.API,m=t.pdfEscape16=function(t,e){for(var n,r=e.metadata.Unicode.widths,i=["","0","00","000","0000"],a=[""],o=0,s=t.length;o>"),n("endobj");var d=r();n("<<"),n("/Type /Font"),n("/BaseFont /"+a(e.fontName)),n("/FontDescriptor "+f+" 0 R"),n("/W "+p.API.PDFObject.convert(o)),n("/CIDToGIDMap /Identity"),n("/DW 1000"),n("/Subtype /CIDFontType2"),n("/CIDSystemInfo"),n("<<"),n("/Supplement 0"),n("/Registry (Adobe)"),n("/Ordering ("+e.encoding+")"),n(">>"),n(">>"),n("endobj"),e.objectNumber=r(),n("<<"),n("/Type /Font"),n("/Subtype /Type0"),n("/ToUnicode "+h+" 0 R"),n("/BaseFont /"+e.fontName),n("/Encoding /"+e.encoding),n("/DescendantFonts ["+d+" 0 R]"),n(">>"),n("endobj"),e.isAlreadyPutted=!0}}(t)}]);t.events.push(["putFont",function(t){!function(t){var e=t.font,n=t.out,r=t.newObject,i=t.putStream,a=t.pdfEscapeWithNeededParanthesis;if(e.metadata instanceof p.API.TTFFont&&"WinAnsiEncoding"===e.encoding){for(var o=e.metadata.rawData,s="",u=0;u>"),n("endobj"),e.objectNumber=r();for(var f=0;f>"),n("endobj"),e.isAlreadyPutted=!0}}(t)}]);function a(t){var e,n=t.text||"",r=t.x,i=t.y,a=t.options||{},o=t.mutex||{},s=o.pdfEscape,u=o.activeFontKey,l=o.fonts,c=u,h="",f=0,d="",p=l[c].encoding;if("Identity-H"!==l[c].encoding)return{text:n,x:r,y:i,options:a,mutex:o};for(d=n,c=u,Array.isArray(n)&&(d=n[0]),f=0;fy-l.top-l.bottom&&s.pagesplit){var d=function(t,e,n,r,i){var a=document.createElement("canvas");a.height=i,a.width=r;var o=a.getContext("2d");return o.mozImageSmoothingEnabled=!1,o.webkitImageSmoothingEnabled=!1,o.msImageSmoothingEnabled=!1,o.imageSmoothingEnabled=!1,o.fillStyle=s.backgroundColor||"#ffffff",o.fillRect(0,0,r,i),o.drawImage(t,e,n,r,i,0,0,r,i),a},n=function(){for(var t,e,n,r,i=0,a=0,o={},s=!1;;){if(a=0,o.top=0!==i?l.top:g,o.left=0!==i?l.left:p,s=(v-l.left-l.right)*b=u.width);)this.addPage();else r=[n=d(u,0,i,t,e),o.left,o.top,n.width/b,n.height/b,h,null,f],this.addImage.apply(this,r);if((i+=e)>=u.height)break;this.addPage()}m(c,i,null,r)}.bind(this);if("CANVAS"===u.nodeName){var r=new Image;r.onload=n,r.src=u.toDataURL("image/png"),u=r}else n()}else{var i=Math.random().toString(35),a=[u,p,g,c,e,h,i,f];this.addImage.apply(this,a),m(c,e,i,a)}}.bind(this),"undefined"!=typeof html2canvas&&!s.rstz)return html2canvas(t,s);if("undefined"==typeof rasterizeHTML)return null;var n="drawDocument";return"string"==typeof t&&(n=/^http/.test(t)?"drawURL":"drawHTML"),s.width=s.width||v*b,rasterizeHTML[n](t,void 0,s).then(function(t){s.onrendered(t.image)},function(t){m(null,t)})}, +/** + * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser + * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com + * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria + * 2014 Diego Casorran, https://github.com/diegocr + * 2014 Daniel Husar, https://github.com/danielhusar + * 2014 Wolfgang Gassler, https://github.com/woolfg + * 2014 Steven Spungin, https://github.com/flamenco + * + * @license + * + * ==================================================================== + */ +function(t){var k,F,i,o,s,u,l,c,C,y,f,h,d,n,I,j,p,g,m,B;function e(){}k=function(t){return e.prototype=t,new e},y=function(t){var e,n,r,i,a,o,s;for(n=0,r=t.length,e=void 0,o=i=!1;!i&&n!==r;)(e=t[n]=t[n].trimLeft())&&(i=!0),n++;for(n=r-1;r&&!o&&-1!==n;)(e=t[n]=t[n].trimRight())&&(o=!0),n--;for(a=/\s+$/g,s=!0,n=0;n!==r;)"\u2028"!=t[n]&&(e=t[n].replace(/\s+/g," "),s&&(e=e.trimLeft()),e&&(s=a.test(e)),t[n]=e),n++;return t},h=function(t){var e,n,r;for(e=void 0,n=(r=t.split(",")).shift();!e&&n;)e=i[n.trim().toLowerCase()],n=r.shift();return e},d=function(t){var e;return-1<(t="auto"===t?"0px":t).indexOf("em")&&!isNaN(Number(t.replace("em","")))&&(t=18.719*Number(t.replace("em",""))+"px"),-1i.pdf.margins_doc.top&&(i.pdf.addPage(),i.y=i.pdf.margins_doc.top,i.executeWatchFunctions(n));var w=C(n),x=i.x,N=12/i.pdf.internal.scaleFactor,L=(w["margin-left"]+w["padding-left"])*N,A=(w["margin-right"]+w["padding-right"])*N,_=(w["margin-top"]+w["padding-top"])*N,S=(w["margin-bottom"]+w["padding-bottom"])*N;void 0!==w.float&&"right"===w.float?x+=i.settings.width-n.width-A:x+=L,i.pdf.addImage(v,x,i.y+_,n.width,n.height),v=void 0,"right"===w.float||"left"===w.float?(i.watchFunctions.push(function(t,e,n,r){return i.y>=e?(i.x+=t,i.settings.width+=n,!0):!!(r&&1===r.nodeType&&!O[r.nodeName]&&i.x+r.width>i.pdf.margins_doc.left+i.pdf.margins_doc.width)&&(i.x+=t,i.y=e,i.settings.width+=n,!0)}.bind(this,"left"===w.float?-n.width-L-A:0,i.y+n.height+_+S,n.width)),i.watchFunctions.push(function(t,e,n){return!(i.y]*?>/gi,""),l="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),(u=document.createElement("div")).style.cssText="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",u.innerHTML='