From be38b260a1a3084ce627f3250e0ded62f4f87134 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 31 Jan 2019 14:58:51 -0500 Subject: [PATCH 01/77] fixes #49 --- .../extentreports/reporter/ExtentKlovReporter.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java index b48eb3d..f857b82 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -441,7 +441,7 @@ public synchronized void flush(ReportAggregates reportAggregates) { .append("errorParentLength", stats.getParentCountError()) .append("warningParentLength", stats.getParentCountWarning()) .append("skipParentLength", stats.getParentCountSkip()) - .append("exceptionsParentLength", stats.getChildCountExceptions()) + .append("exceptionsParentLength", stats.getParentCountExceptions()) .append("childLength", stats.getChildCount()) .append("passChildLength", stats.getChildCountPass()) .append("failChildLength", stats.getChildCountFail()) @@ -566,7 +566,12 @@ public synchronized void onLogAdded(Test test, Log log) { .append("status", log.getStatus().toString()) .append("timestamp", log.getTimestamp()) .append("details", log.getDetails()); - + + if (log.getExceptionInfo() != null) { + doc.append("exception", log.getExceptionInfo().getExceptionName()) + .append("stacktrace", log.getExceptionInfo().getStackTrace()); + } + if (log.hasScreenCapture() && log.getScreenCaptureContext().getFirst().isBase64()) { doc.append("details", log.getDetails() + log.getScreenCaptureContext().getFirst().getSource()); } From 553d0a3029c07502267c9eb983735a16770abd01 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 31 Jan 2019 15:06:05 -0500 Subject: [PATCH 02/77] fixes #45 --- .../view/v3html/test-view/v3-html-test-view-charts.ftl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view-charts.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view-charts.ftl index 882f23c..1b1fbed 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view-charts.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view-charts.ftl @@ -18,7 +18,7 @@ ${ report.reportStatusStats.parentCountPass } ${parentLabel} passed
- ${ report.reportStatusStats.parentCountFail + report.reportStatusStats.parentCountFatal } ${parentLabel} failed, ${ report.reportStatusStats.parentCountError + report.reportStatusStats.parentCountWarning + report.reportStatusStats.parentCountSkip } others + ${ report.reportStatusStats.parentCountFail + report.reportStatusStats.parentCountFatal } ${parentLabel} failed, ${ report.reportStatusStats.parentCountSkip } skipped
@@ -33,7 +33,9 @@ ${ report.reportStatusStats.childCountPass } ${childLabel} passed
- ${ report.reportStatusStats.childCountFail + report.reportStatusStats.childCountFatal } ${childLabel} failed, ${ report.reportStatusStats.childCountError + report.reportStatusStats.childCountWarning + report.reportStatusStats.childCountSkip + report.reportStatusStats.childCountInfo } others + ${ report.reportStatusStats.childCountFail + report.reportStatusStats.childCountFatal } ${childLabel} failed, + ${report.reportStatusStats.childCountSkip} skipped, + ${ report.reportStatusStats.childCountError + report.reportStatusStats.childCountWarning + report.reportStatusStats.childCountInfo } others
@@ -49,7 +51,9 @@ ${ report.reportStatusStats.grandChildCountPass } ${grandChildLabel} passed
- ${ report.reportStatusStats.grandChildCountFail + report.reportStatusStats.grandChildCountFatal } ${grandChildLabel} failed, ${ report.reportStatusStats.grandChildCountSkip + report.reportStatusStats.grandChildCountError + report.reportStatusStats.grandChildCountWarning + report.reportStatusStats.grandChildCountInfo } others + ${ report.reportStatusStats.grandChildCountFail + report.reportStatusStats.grandChildCountFatal } ${childLabel} failed, + ${report.reportStatusStats.grandChildCountSkip} skipped, + ${ report.reportStatusStats.grandChildCountError + report.reportStatusStats.grandChildCountWarning + report.reportStatusStats.grandChildCountInfo } others
From 2ec04098b52b7bce678bfed62c0860f7f3bb2d95 Mon Sep 17 00:00:00 2001 From: Anshoo Arora Date: Thu, 7 Feb 2019 12:33:07 -0500 Subject: [PATCH 03/77] Offline mode (#52) * #41 offlineMode * Update spark-style.css closes #41 --- config/spark-config.xml | 3 + config/v3html-config.xml | 3 + .../reporter/BasicFileReporter.java | 12 +- .../reporter/ExtentHtmlReporter.java | 6 +- .../reporter/ExtentSparkReporter.java | 4 + .../ExtentHtmlReporterConfiguration.java | 75 ++ .../ExtentSparkReporterConfiguration.java | 75 ++ .../offline/commons/js/jsontree.js | 2 + .../offline/spark/css/spark-style.css | 482 ++++++++++ .../offline/spark/js/spark-script.js | 199 ++++ .../offline/v3html/css/v3html-style.css | 847 ++++++++++++++++++ .../offline/v3html/js/v3html-script.js | 606 +++++++++++++ .../view/spark/partials/head.ftl | 15 +- .../view/spark/partials/scripts.ftl | 6 +- .../extentreports/view/spark/test.ftl | 6 +- .../view/v3html/v3-html-head.ftl | 11 +- .../view/v3html/v3-html-index.ftl | 9 +- 17 files changed, 2342 insertions(+), 19 deletions(-) create mode 100644 src/main/resources/com/aventstack/extentreports/offline/commons/js/jsontree.js create mode 100644 src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css create mode 100644 src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js create mode 100644 src/main/resources/com/aventstack/extentreports/offline/v3html/css/v3html-style.css create mode 100644 src/main/resources/com/aventstack/extentreports/offline/v3html/js/v3html-script.js diff --git a/config/spark-config.xml b/config/spark-config.xml index 0d40510..5da2252 100644 --- a/config/spark-config.xml +++ b/config/spark-config.xml @@ -14,6 +14,9 @@ https + + false + Extent Framework diff --git a/config/v3html-config.xml b/config/v3html-config.xml index 0d40510..5da2252 100644 --- a/config/v3html-config.xml +++ b/config/v3html-config.xml @@ -14,6 +14,9 @@ https + + false + Extent Framework diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index 9b00c02..f9c2257 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -310,13 +310,13 @@ protected Configuration getFreemarkerConfig() { } protected Boolean enforceOfflineMode() { - if (configContext.containsKey("enableOfflineMode")) { - String offlineMode = String.valueOf(configContext.getValue("enableOfflineMode")); - if (!configContext.containsKey("offlineDirectory") && offlineMode.equals("true")) { - return true; - } + if (configContext.containsKey("enableOfflineMode")) { + String offlineMode = String.valueOf(configContext.getValue("enableOfflineMode")); + if (!configContext.containsKey("offlineDirectory") && offlineMode.equals("true")) { + return true; + } } - return false; + return false; } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java index 8306918..0c005c5 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java @@ -18,7 +18,7 @@ public class ExtentHtmlReporter extends BasicFileReporter { private static final Logger logger = Logger.getLogger(ExtentHtmlReporter.class.getName()); - private static final String REPORTER_NAME = "html"; + private static final String REPORTER_NAME = "v3html"; private static final String TEMPLATE_NAME = "v3html/v3-html-index.ftl"; private static final String[] DEFAULT_CONFIG_FILE_PATH = new String[] { "html.properties", "src/main/resources/html.properties" }; @@ -46,6 +46,10 @@ public synchronized void flush(ReportAggregates reportAggregates) { if (getTestList().isEmpty()) return; + if (enforceOfflineMode()) { + userConfig.enableOfflineMode(true); + } + loadUserConfig(); try { diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java index 5dd9d43..91e6e59 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java @@ -49,6 +49,10 @@ public synchronized void flush(ReportAggregates reportAggregates) { if (getTestList().isEmpty()) return; + if (enforceOfflineMode()) { + userConfig.enableOfflineMode(true); + } + loadUserConfig(); try { diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java index 9391cfc..7fbaec1 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java @@ -1,6 +1,12 @@ package com.aventstack.extentreports.reporter.configuration; +import java.io.File; +import java.util.stream.Stream; + +import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.reporter.ExtentHtmlReporter; +import com.aventstack.extentreports.resource.OfflineResxDelegate; +import com.aventstack.extentreports.utils.FileUtil; /** * Defines configuration settings for the HTML reporter @@ -11,5 +17,74 @@ public class ExtentHtmlReporterConfiguration public ExtentHtmlReporterConfiguration(ExtentHtmlReporter reporter) { super(reporter); } + + /** + * Creates the HTML report, saving all resources (css, js, fonts) in the same + * location, so the report can be viewed without an internet connection + * + * @param offline Setting to enable an offline accessible report + */ + public void enableOfflineMode(Boolean offline) { + usedConfigs.put("enableOfflineMode", String.valueOf(offline)); + usedConfigs.put("offlineDirectory", getReporter().getReporterName() + "/"); + if (offline) { + File f = getTargetDirectory(((ExtentHtmlReporter) getReporter()).getFileFile()); + String s = "/"; + String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); + resourcePackagePath += s + "offline" + s; + String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); + OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); + } + } + + private File getTargetDirectory(File f) { + String dir; + if (FileUtil.isDirectory(f)) { + dir = f.getAbsolutePath().replace("\\", "/"); + } else { + dir = f.getAbsolutePath().replace("\\", "/"); + dir = new File(dir).getParent(); + } + dir += "/" + getReporter().getReporterName(); + return new File(dir); + } + + private String[] combine(String[]... array) { + String[] result = new String[] {}; + for (String[] arr : array) { + result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); + } + return result; + } + + private String[] getJSFiles() { + String commonsPath = "commons/js/"; + String reporterPath = getReporter().getReporterName() + "/js/"; + String[] files = { reporterPath + "v3html-script.js", commonsPath + "jsontree.js" }; + return files; + } + + private String[] getCSSFiles() { + String stylesPath = "css/"; + String reporterPath = getReporter().getReporterName() + "/" + stylesPath; + String[] files = { reporterPath + "v3html-style.css" }; + return files; + } + + private String[] getIconFiles() { + String path = "commons/css/icons/"; + String iconDirPath = "material/"; + String[] files = { path + "material-icons.css", path + iconDirPath + "MaterialIcons-Regular.eot", + path + iconDirPath + "MaterialIcons-Regular.ijmap", path + iconDirPath + "MaterialIcons-Regular.svg", + path + iconDirPath + "MaterialIcons-Regular.ttf", path + iconDirPath + "MaterialIcons-Regular.woff", + path + iconDirPath + "MaterialIcons-Regular.woff2" }; + return files; + } + + private String[] getImgFiles() { + String path = "commons/img/"; + String[] files = { path + "logo.png" }; + return files; + } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java index af9da95..cfbc8db 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java @@ -1,6 +1,12 @@ package com.aventstack.extentreports.reporter.configuration; +import java.io.File; +import java.util.stream.Stream; + +import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.reporter.ExtentSparkReporter; +import com.aventstack.extentreports.resource.OfflineResxDelegate; +import com.aventstack.extentreports.utils.FileUtil; /** * Defines configuration settings for the Spark reporter @@ -11,5 +17,74 @@ public class ExtentSparkReporterConfiguration public ExtentSparkReporterConfiguration(ExtentSparkReporter reporter) { super(reporter); } + + /** + * Creates the HTML report, saving all resources (css, js, fonts) in the same + * location, so the report can be viewed without an internet connection + * + * @param offline Setting to enable an offline accessible report + */ + public void enableOfflineMode(Boolean offline) { + usedConfigs.put("enableOfflineMode", String.valueOf(offline)); + usedConfigs.put("offlineDirectory", getReporter().getReporterName() + "/"); + if (offline) { + File f = getTargetDirectory(((ExtentSparkReporter) getReporter()).getFileFile()); + String s = "/"; + String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); + resourcePackagePath += s + "offline" + s; + String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); + OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); + } + } + + private File getTargetDirectory(File f) { + String dir; + if (FileUtil.isDirectory(f)) { + dir = f.getAbsolutePath().replace("\\", "/"); + } else { + dir = f.getAbsolutePath().replace("\\", "/"); + dir = new File(dir).getParent(); + } + dir += "/" + getReporter().getReporterName(); + return new File(dir); + } + + private String[] combine(String[]... array) { + String[] result = new String[] {}; + for (String[] arr : array) { + result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); + } + return result; + } + + private String[] getJSFiles() { + String commonsPath = "commons/js/"; + String reporterPath = getReporter().getReporterName() + "/js/"; + String[] files = { reporterPath + "spark-script.js", commonsPath + "jsontree.js" }; + return files; + } + + private String[] getCSSFiles() { + String stylesPath = "css/"; + String reporterPath = getReporter().getReporterName() + "/" + stylesPath; + String[] files = { reporterPath + "spark-style.css" }; + return files; + } + + private String[] getIconFiles() { + String path = "commons/css/icons/"; + String iconDirPath = "fontawesome/"; + String[] files = { path + "font-awesome.min.css", path + iconDirPath + "fontawesome-webfont.eot", + path + iconDirPath + "fontawesome-webfont.svg", path + iconDirPath + "fontawesome-webfont.ttf", + path + iconDirPath + "fontawesome-webfont.woff", path + iconDirPath + "fontawesome-webfont.woff2", + path + iconDirPath + "FontAwesome.otf" }; + return files; + } + + private String[] getImgFiles() { + String path = "commons/img/"; + String[] files = { path + "logo.png" }; + return files; + } } diff --git a/src/main/resources/com/aventstack/extentreports/offline/commons/js/jsontree.js b/src/main/resources/com/aventstack/extentreports/offline/commons/js/jsontree.js new file mode 100644 index 0000000..a539d1b --- /dev/null +++ b/src/main/resources/com/aventstack/extentreports/offline/commons/js/jsontree.js @@ -0,0 +1,2 @@ +/*! json-tree - v0.2.2 - 2017-09-25, MIT LICENSE */ +var JSONTree=function(){var n={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},t=0,r=0;this.create=function(n,t){return r+=1,N(u(n,0,!1),{class:"jstValue"})};var e=function(t){return t.replace(/[&<>'"]/g,function(t){return n[t]})},s=function(){return r+"_"+t++},u=function(n,t,r){if(null===n)return f(r?t:0);switch(typeof n){case"boolean":return l(n,r?t:0);case"number":return i(n,r?t:0);case"string":return o(n,r?t:0);default:return n instanceof Array?a(n,t,r):c(n,t,r)}},c=function(n,t,r){var e=s(),u=Object.keys(n).map(function(r){return j(r,n[r],t+1,!0)}).join(m()),c=[g("{",r?t:0,e),N(u,{id:e}),p("}",t)].join("\n");return N(c,{})},a=function(n,t,r){var e=s(),c=n.map(function(n){return u(n,t+1,!0)}).join(m());return[g("[",r?t:0,e),N(c,{id:e}),p("]",t)].join("\n")},o=function(n,t){var r=e(JSON.stringify(n));return N(v(r,t),{class:"jstStr"})},i=function(n,t){return N(v(n,t),{class:"jstNum"})},l=function(n,t){return N(v(n,t),{class:"jstBool"})},f=function(n){return N(v("null",n),{class:"jstNull"})},j=function(n,t,r){var s=v(e(JSON.stringify(n))+": ",r),c=N(u(t,r,!1),{});return N(s+c,{class:"jstProperty"})},m=function(){return N(",\n",{class:"jstComma"})},N=function(n,t){return d("span",t,n)},d=function(n,t,r){return"<"+n+Object.keys(t).map(function(n){return" "+n+'="'+t[n]+'"'}).join("")+">"+r+""},g=function(n,t,r){return N(v(n,t),{class:"jstBracket"})+N("",{class:"jstFold",onclick:"JSONTree.toggle('"+r+"')"})};this.toggle=function(n){var t=document.getElementById(n),r=t.parentNode,e=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",r.className="jstFolded",e.className="jstExpand"):(t.className="",r.className="",e.className="jstFold")};var p=function(n,t){return N(v(n,t),{})},v=function(n,t){return Array(2*t+1).join(" ")+n};return this}(); diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css new file mode 100644 index 0000000..8dd9007 --- /dev/null +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css @@ -0,0 +1,482 @@ +@import url("https://fonts.googleapis.com/css?family=Roboto:400,500"); + +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */: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,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%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-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:#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;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}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}dfn{font-style:italic}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;-webkit-text-decoration-skip:objects}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:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}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}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[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-cancel-button,[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-family:inherit;font-weight:500;line-height:1.2;color:inherit}.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,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}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:-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,.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%;min-height:1px;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%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@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%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@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%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@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%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@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%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.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 .table{background-color:#fff}.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-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.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-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-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-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-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-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-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-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:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.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{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;-ms-overflow-style:-ms-autohiding-scrollbar}.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;-ms-overflow-style:-ms-autohiding-scrollbar}.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;-ms-overflow-style:-ms-autohiding-scrollbar}.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;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;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}.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::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}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;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.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-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.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-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.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:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.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:.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:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control: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,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control: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{background-color:#71dd8a}.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{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 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.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~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.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{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:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control: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,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control: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{background-color:#efa2a9}.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{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 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.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~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.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{box-shadow:0 0 0 .2rem rgba(220,53,69,.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{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;margin-top:0;margin-right:.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;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;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}.btn:focus,.btn:hover{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}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}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(0,123,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(0,123,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(108,117,125,.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(108,117,125,.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(40,167,69,.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(40,167,69,.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(23,162,184,.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(23,162,184,.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(255,193,7,.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(255,193,7,.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(220,53,69,.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(220,53,69,.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(248,249,250,.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(248,249,250,.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(52,58,64,.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(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.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{opacity:0;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;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}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;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{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;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{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;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-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;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}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 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-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.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:first-child{margin-left:0}.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{margin-left: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{-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+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-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:-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>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.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{margin-left:-1px}.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:-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::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-webkit-box;display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.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:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;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>.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:-webkit-inline-box;display:-ms-inline-flexbox;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;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-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{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%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{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%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::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%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-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%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;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.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{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;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(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.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:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.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{-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:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{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:.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:-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:.5rem;padding-bottom:.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:.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:not(:disabled):not(.disabled){cursor:pointer}.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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-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}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-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}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-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}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-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-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.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{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 .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-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-expand .dropup .dropdown-menu{top:auto;bottom:100%}.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;charset=utf8,%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;charset=utf8,%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:-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,.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{-webkit-box-flex:1;-ms-flex:1 1 auto;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:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-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{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-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:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.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:-webkit-box;display:-ms-flexbox;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{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-link:not(:disabled):not(.disabled){cursor:pointer}.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}.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}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.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}@-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:.75rem;background-color:#e9ecef;border-radius:.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;color:#fff;text-align:center;background-color:#007bff;transition:width .6s ease}.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{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.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:focus,.list-group-item-action:hover{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:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{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:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.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% - (.5rem * 2))}.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,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.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;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding: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;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.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-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-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:-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::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom: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-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::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left: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-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::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;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::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;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-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;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:.5}.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:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%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;charset=utf8,%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:10px;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{position:relative;-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;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.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{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-circle{border-radius:50%!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 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.857143%}.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}.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}.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}.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}.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}.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}}.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;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;-webkit-clip-path:none;clip-path:none}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.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-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-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-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-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-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-justify{text-align:justify!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-normal{font-weight:400!important}.font-weight-bold{font-weight:700!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:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-muted{color:#6c757d!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.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 #ddd!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ + + + + +/* perfect-scrollbar v0.6.16 */ +.ps-container{-ms-touch-action:auto;touch-action:auto;overflow:hidden !important;-ms-overflow-style:none}@supports (-ms-overflow-style: none){.ps-container{overflow:auto !important}}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){.ps-container{overflow:auto !important}}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block;background-color:transparent}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;bottom:0px;height:15px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;bottom:2px;height:6px}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x,.ps-container>.ps-scrollbar-x-rail:active>.ps-scrollbar-x{height:11px}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;right:0;width:15px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;right:2px;width:6px}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y,.ps-container>.ps-scrollbar-y-rail:active>.ps-scrollbar-y{width:11px}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999} + + + + +@charset "UTF-8"; + +/*! + * animate.css -http://daneden.me/animate + * Version - 3.7.0 + * Licensed under the MIT license - http://opensource.org/licenses/MIT + * + * Copyright (c) 2018 Daniel Eden + */ + +@-webkit-keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);animation-timing-function:cubic-bezier(.215,.61,.355,1);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);animation-timing-function:cubic-bezier(.215,.61,.355,1);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;-webkit-transform-origin:center bottom;animation-name:bounce;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.headShake{-webkit-animation-name:headShake;-webkit-animation-timing-function:ease-in-out;animation-name:headShake;animation-timing-function:ease-in-out}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-animation-name:swing;-webkit-transform-origin:top center;animation-name:swing;transform-origin:top center}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;-webkit-transform-origin:center;animation-name:jello;transform-origin:center}@-webkit-keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}.heartBeat{-webkit-animation-duration:1.3s;-webkit-animation-name:heartBeat;-webkit-animation-timing-function:ease-in-out;animation-duration:1.3s;animation-name:heartBeat;animation-timing-function:ease-in-out}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{-webkit-transform:scale3d(1.03,1.03,1.03);opacity:1;transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{-webkit-transform:scaleX(1);opacity:1;transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{-webkit-transform:scale3d(1.03,1.03,1.03);opacity:1;transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{-webkit-transform:scaleX(1);opacity:1;transform:scaleX(1)}}.bounceIn{-webkit-animation-duration:.75s;-webkit-animation-name:bounceIn;animation-duration:.75s;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,-3000px,0);opacity:0;transform:translate3d(0,-3000px,0)}60%{-webkit-transform:translate3d(0,25px,0);opacity:1;transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,-3000px,0);opacity:0;transform:translate3d(0,-3000px,0)}60%{-webkit-transform:translate3d(0,25px,0);opacity:1;transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(-3000px,0,0);opacity:0;transform:translate3d(-3000px,0,0)}60%{-webkit-transform:translate3d(25px,0,0);opacity:1;transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(-3000px,0,0);opacity:0;transform:translate3d(-3000px,0,0)}60%{-webkit-transform:translate3d(25px,0,0);opacity:1;transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(3000px,0,0);opacity:0;transform:translate3d(3000px,0,0)}60%{-webkit-transform:translate3d(-25px,0,0);opacity:1;transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(3000px,0,0);opacity:0;transform:translate3d(3000px,0,0)}60%{-webkit-transform:translate3d(-25px,0,0);opacity:1;transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,3000px,0);opacity:0;transform:translate3d(0,3000px,0)}60%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,3000px,0);opacity:0;transform:translate3d(0,3000px,0)}60%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{-webkit-transform:scale3d(1.1,1.1,1.1);opacity:1;transform:scale3d(1.1,1.1,1.1)}to{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{-webkit-transform:scale3d(1.1,1.1,1.1);opacity:1;transform:scale3d(1.1,1.1,1.1)}to{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-duration:.75s;-webkit-animation-name:bounceOut;animation-duration:.75s;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{-webkit-transform:translate3d(20px,0,0);opacity:1;transform:translate3d(20px,0,0)}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{-webkit-transform:translate3d(20px,0,0);opacity:1;transform:translate3d(20px,0,0)}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{-webkit-transform:translate3d(-20px,0,0);opacity:1;transform:translate3d(-20px,0,0)}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{-webkit-transform:translate3d(-20px,0,0);opacity:1;transform:translate3d(-20px,0,0)}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{-webkit-transform:translate3d(0,20px,0);opacity:1;transform:translate3d(0,20px,0)}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{-webkit-transform:translate3d(0,20px,0);opacity:1;transform:translate3d(0,20px,0)}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInDown{0%{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInDownBig{0%{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInLeft{0%{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInLeftBig{0%{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInRight{0%{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInRightBig{0%{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInUp{0%{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInUpBig{0%{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn)}40%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg)}50%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg)}80%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg)}to{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg)}}@keyframes flip{0%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn)}40%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg)}50%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg)}80%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg)}to{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg)}}.animated.flip{-webkit-animation-name:flip;-webkit-backface-visibility:visible;animation-name:flip;backface-visibility:visible}@-webkit-keyframes flipInX{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateX(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);opacity:1;transform:perspective(400px) rotateX(10deg)}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateX(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);opacity:1;transform:perspective(400px) rotateX(10deg)}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-animation-name:flipInX;-webkit-backface-visibility:visible!important;animation-name:flipInX;backface-visibility:visible!important}@-webkit-keyframes flipInY{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateY(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);opacity:1;transform:perspective(400px) rotateY(10deg)}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateY(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);opacity:1;transform:perspective(400px) rotateY(10deg)}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-animation-name:flipInY;-webkit-backface-visibility:visible!important;animation-name:flipInY;backface-visibility:visible!important}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);opacity:1;transform:perspective(400px) rotateX(-20deg)}to{-webkit-transform:perspective(400px) rotateX(90deg);opacity:0;transform:perspective(400px) rotateX(90deg)}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);opacity:1;transform:perspective(400px) rotateX(-20deg)}to{-webkit-transform:perspective(400px) rotateX(90deg);opacity:0;transform:perspective(400px) rotateX(90deg)}}.flipOutX{-webkit-animation-duration:.75s;-webkit-animation-name:flipOutX;-webkit-backface-visibility:visible!important;animation-duration:.75s;animation-name:flipOutX;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);opacity:1;transform:perspective(400px) rotateY(-15deg)}to{-webkit-transform:perspective(400px) rotateY(90deg);opacity:0;transform:perspective(400px) rotateY(90deg)}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);opacity:1;transform:perspective(400px) rotateY(-15deg)}to{-webkit-transform:perspective(400px) rotateY(90deg);opacity:0;transform:perspective(400px) rotateY(90deg)}}.flipOutY{-webkit-animation-duration:.75s;-webkit-animation-name:flipOutY;-webkit-backface-visibility:visible!important;animation-duration:.75s;animation-name:flipOutY;backface-visibility:visible!important}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);opacity:0;transform:translate3d(100%,0,0) skewX(-30deg)}60%{-webkit-transform:skewX(20deg);opacity:1;transform:skewX(20deg)}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);opacity:0;transform:translate3d(100%,0,0) skewX(-30deg)}60%{-webkit-transform:skewX(20deg);opacity:1;transform:skewX(20deg)}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-name:lightSpeedIn;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);opacity:0;transform:translate3d(100%,0,0) skewX(30deg)}}@keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);opacity:0;transform:translate3d(100%,0,0) skewX(30deg)}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-name:lightSpeedOut;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(-200deg);transform-origin:center}to{-webkit-transform:translateZ(0);-webkit-transform-origin:center;opacity:1;transform:translateZ(0);transform-origin:center}}@keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(-200deg);transform-origin:center}to{-webkit-transform:translateZ(0);-webkit-transform-origin:center;opacity:1;transform:translateZ(0);transform-origin:center}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}@keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(45deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}@keyframes rotateInDownRight{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(45deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}@keyframes rotateInUpLeft{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-90deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}@keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-90deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;opacity:1;transform-origin:center}to{-webkit-transform:rotate(200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(200deg);transform-origin:center}}@keyframes rotateOut{0%{-webkit-transform-origin:center;opacity:1;transform-origin:center}to{-webkit-transform:rotate(200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(200deg);transform-origin:center}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-45deg);transform-origin:right bottom}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-45deg);transform-origin:right bottom}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(90deg);transform-origin:right bottom}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(90deg);transform-origin:right bottom}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-animation-timing-function:ease-in-out;-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform-origin:top left}20%,60%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(80deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(60deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;opacity:1;transform:rotate(60deg);transform-origin:top left}to{-webkit-transform:translate3d(0,700px,0);opacity:0;transform:translate3d(0,700px,0)}}@keyframes hinge{0%{-webkit-animation-timing-function:ease-in-out;-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform-origin:top left}20%,60%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(80deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(60deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;opacity:1;transform:rotate(60deg);transform-origin:top left}to{-webkit-transform:translate3d(0,700px,0);opacity:0;transform:translate3d(0,700px,0)}}.hinge{-webkit-animation-duration:2s;-webkit-animation-name:hinge;animation-duration:2s;animation-name:hinge}@-webkit-keyframes jackInTheBox{0%{-webkit-transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;opacity:0;transform:scale(.1) rotate(30deg);transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{-webkit-transform:scale(1);opacity:1;transform:scale(1)}}@keyframes jackInTheBox{0%{-webkit-transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;opacity:0;transform:scale(.1) rotate(30deg);transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{-webkit-transform:scale(1);opacity:1;transform:scale(1)}}.jackInTheBox{-webkit-animation-name:jackInTheBox;animation-name:jackInTheBox}@-webkit-keyframes rollIn{0%{-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);opacity:0;transform:translate3d(-100%,0,0) rotate(-120deg)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes rollIn{0%{-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);opacity:0;transform:translate3d(-100%,0,0) rotate(-120deg)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) rotate(120deg);opacity:0;transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) rotate(120deg);opacity:0;transform:translate3d(100%,0,0) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}}@keyframes zoomInDown{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(10px,0,0)}}@keyframes zoomInLeft{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(10px,0,0)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-10px,0,0)}}@keyframes zoomInRight{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-10px,0,0)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}}@keyframes zoomInUp{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform-origin:center bottom}}@keyframes zoomOutDown{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform-origin:center bottom}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{-webkit-transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;opacity:0;transform:scale(.1) translate3d(-2000px,0,0);transform-origin:left center}}@keyframes zoomOutLeft{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{-webkit-transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;opacity:0;transform:scale(.1) translate3d(-2000px,0,0);transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{-webkit-transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;opacity:0;transform:scale(.1) translate3d(2000px,0,0);transform-origin:right center}}@keyframes zoomOutRight{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{-webkit-transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;opacity:0;transform:scale(.1) translate3d(2000px,0,0);transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform-origin:center bottom}}@keyframes zoomOutUp{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform-origin:center bottom}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:hidden}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:hidden}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:hidden}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:hidden}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:hidden}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:hidden}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:hidden}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:hidden}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}.animated{-webkit-animation-duration:1s;-webkit-animation-fill-mode:both;animation-duration:1s;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media (prefers-reduced-motion){.animated{-webkit-animation:unset!important;-webkit-transition:none!important;animation:unset!important;transition:none!important}} + + + + +/*! + * Materialize v1.0.0 (http://materializecss.com) + * Copyright 2014-2017 Materialize + * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) + */ +.red{background-color:#F44336!important}.red-text{color:#F44336!important}.red.lighten-5{background-color:#FFEBEE!important}.red-text.text-lighten-5{color:#FFEBEE!important}.red.lighten-4{background-color:#FFCDD2!important}.red-text.text-lighten-4{color:#FFCDD2!important}.red.lighten-3{background-color:#EF9A9A!important}.red-text.text-lighten-3{color:#EF9A9A!important}.red.lighten-2{background-color:#E57373!important}.red-text.text-lighten-2{color:#E57373!important}.red.lighten-1{background-color:#EF5350!important}.red-text.text-lighten-1{color:#EF5350!important}.red.darken-1{background-color:#E53935!important}.red-text.text-darken-1{color:#E53935!important}.red.darken-2{background-color:#D32F2F!important}.red-text.text-darken-2{color:#D32F2F!important}.red.darken-3{background-color:#C62828!important}.red-text.text-darken-3{color:#C62828!important}.red.darken-4{background-color:#B71C1C!important}.red-text.text-darken-4{color:#B71C1C!important}.red.accent-1{background-color:#FF8A80!important}.red-text.text-accent-1{color:#FF8A80!important}.red.accent-2{background-color:#FF5252!important}.red-text.text-accent-2{color:#FF5252!important}.red.accent-3{background-color:#FF1744!important}.red-text.text-accent-3{color:#FF1744!important}.red.accent-4{background-color:#D50000!important}.red-text.text-accent-4{color:#D50000!important}.pink{background-color:#e91e63!important}.pink-text{color:#e91e63!important}.pink.lighten-5{background-color:#fce4ec!important}.pink-text.text-lighten-5{color:#fce4ec!important}.pink.lighten-4{background-color:#f8bbd0!important}.pink-text.text-lighten-4{color:#f8bbd0!important}.pink.lighten-3{background-color:#f48fb1!important}.pink-text.text-lighten-3{color:#f48fb1!important}.pink.lighten-2{background-color:#f06292!important}.pink-text.text-lighten-2{color:#f06292!important}.pink.lighten-1{background-color:#ec407a!important}.pink-text.text-lighten-1{color:#ec407a!important}.pink.darken-1{background-color:#d81b60!important}.pink-text.text-darken-1{color:#d81b60!important}.pink.darken-2{background-color:#c2185b!important}.pink-text.text-darken-2{color:#c2185b!important}.pink.darken-3{background-color:#ad1457!important}.pink-text.text-darken-3{color:#ad1457!important}.pink.darken-4{background-color:#880e4f!important}.pink-text.text-darken-4{color:#880e4f!important}.pink.accent-1{background-color:#ff80ab!important}.pink-text.text-accent-1{color:#ff80ab!important}.pink.accent-2{background-color:#ff4081!important}.pink-text.text-accent-2{color:#ff4081!important}.pink.accent-3{background-color:#f50057!important}.pink-text.text-accent-3{color:#f50057!important}.pink.accent-4{background-color:#c51162!important}.pink-text.text-accent-4{color:#c51162!important}.purple{background-color:#9c27b0!important}.purple-text{color:#9c27b0!important}.purple.lighten-5{background-color:#f3e5f5!important}.purple-text.text-lighten-5{color:#f3e5f5!important}.purple.lighten-4{background-color:#e1bee7!important}.purple-text.text-lighten-4{color:#e1bee7!important}.purple.lighten-3{background-color:#ce93d8!important}.purple-text.text-lighten-3{color:#ce93d8!important}.purple.lighten-2{background-color:#ba68c8!important}.purple-text.text-lighten-2{color:#ba68c8!important}.purple.lighten-1{background-color:#ab47bc!important}.purple-text.text-lighten-1{color:#ab47bc!important}.purple.darken-1{background-color:#8e24aa!important}.purple-text.text-darken-1{color:#8e24aa!important}.purple.darken-2{background-color:#7b1fa2!important}.purple-text.text-darken-2{color:#7b1fa2!important}.purple.darken-3{background-color:#6a1b9a!important}.purple-text.text-darken-3{color:#6a1b9a!important}.purple.darken-4{background-color:#4a148c!important}.purple-text.text-darken-4{color:#4a148c!important}.purple.accent-1{background-color:#ea80fc!important}.purple-text.text-accent-1{color:#ea80fc!important}.purple.accent-2{background-color:#e040fb!important}.purple-text.text-accent-2{color:#e040fb!important}.purple.accent-3{background-color:#d500f9!important}.purple-text.text-accent-3{color:#d500f9!important}.purple.accent-4{background-color:#a0f!important}.purple-text.text-accent-4{color:#a0f!important}.deep-purple{background-color:#673ab7!important}.deep-purple-text{color:#673ab7!important}.deep-purple.lighten-5{background-color:#ede7f6!important}.deep-purple-text.text-lighten-5{color:#ede7f6!important}.deep-purple.lighten-4{background-color:#d1c4e9!important}.deep-purple-text.text-lighten-4{color:#d1c4e9!important}.deep-purple.lighten-3{background-color:#b39ddb!important}.deep-purple-text.text-lighten-3{color:#b39ddb!important}.deep-purple.lighten-2{background-color:#9575cd!important}.deep-purple-text.text-lighten-2{color:#9575cd!important}.deep-purple.lighten-1{background-color:#7e57c2!important}.deep-purple-text.text-lighten-1{color:#7e57c2!important}.deep-purple.darken-1{background-color:#5e35b1!important}.deep-purple-text.text-darken-1{color:#5e35b1!important}.deep-purple.darken-2{background-color:#512da8!important}.deep-purple-text.text-darken-2{color:#512da8!important}.deep-purple.darken-3{background-color:#4527a0!important}.deep-purple-text.text-darken-3{color:#4527a0!important}.deep-purple.darken-4{background-color:#311b92!important}.deep-purple-text.text-darken-4{color:#311b92!important}.deep-purple.accent-1{background-color:#b388ff!important}.deep-purple-text.text-accent-1{color:#b388ff!important}.deep-purple.accent-2{background-color:#7c4dff!important}.deep-purple-text.text-accent-2{color:#7c4dff!important}.deep-purple.accent-3{background-color:#651fff!important}.deep-purple-text.text-accent-3{color:#651fff!important}.deep-purple.accent-4{background-color:#6200ea!important}.deep-purple-text.text-accent-4{color:#6200ea!important}.indigo{background-color:#3f51b5!important}.indigo-text{color:#3f51b5!important}.indigo.lighten-5{background-color:#e8eaf6!important}.indigo-text.text-lighten-5{color:#e8eaf6!important}.indigo.lighten-4{background-color:#c5cae9!important}.indigo-text.text-lighten-4{color:#c5cae9!important}.indigo.lighten-3{background-color:#9fa8da!important}.indigo-text.text-lighten-3{color:#9fa8da!important}.indigo.lighten-2{background-color:#7986cb!important}.indigo-text.text-lighten-2{color:#7986cb!important}.indigo.lighten-1{background-color:#5c6bc0!important}.indigo-text.text-lighten-1{color:#5c6bc0!important}.indigo.darken-1{background-color:#3949ab!important}.indigo-text.text-darken-1{color:#3949ab!important}.indigo.darken-2{background-color:#303f9f!important}.indigo-text.text-darken-2{color:#303f9f!important}.indigo.darken-3{background-color:#283593!important}.indigo-text.text-darken-3{color:#283593!important}.indigo.darken-4{background-color:#1a237e!important}.indigo-text.text-darken-4{color:#1a237e!important}.indigo.accent-1{background-color:#8c9eff!important}.indigo-text.text-accent-1{color:#8c9eff!important}.indigo.accent-2{background-color:#536dfe!important}.indigo-text.text-accent-2{color:#536dfe!important}.indigo.accent-3{background-color:#3d5afe!important}.indigo-text.text-accent-3{color:#3d5afe!important}.indigo.accent-4{background-color:#304ffe!important}.indigo-text.text-accent-4{color:#304ffe!important}.blue{background-color:#2196F3!important}.blue-text{color:#2196F3!important}.blue.lighten-5{background-color:#E3F2FD!important}.blue-text.text-lighten-5{color:#E3F2FD!important}.blue.lighten-4{background-color:#BBDEFB!important}.blue-text.text-lighten-4{color:#BBDEFB!important}.blue.lighten-3{background-color:#90CAF9!important}.blue-text.text-lighten-3{color:#90CAF9!important}.blue.lighten-2{background-color:#64B5F6!important}.blue-text.text-lighten-2{color:#64B5F6!important}.blue.lighten-1{background-color:#42A5F5!important}.blue-text.text-lighten-1{color:#42A5F5!important}.blue.darken-1{background-color:#1E88E5!important}.blue-text.text-darken-1{color:#1E88E5!important}.blue.darken-2{background-color:#1976D2!important}.blue-text.text-darken-2{color:#1976D2!important}.blue.darken-3{background-color:#1565C0!important}.blue-text.text-darken-3{color:#1565C0!important}.blue.darken-4{background-color:#0D47A1!important}.blue-text.text-darken-4{color:#0D47A1!important}.blue.accent-1{background-color:#82B1FF!important}.blue-text.text-accent-1{color:#82B1FF!important}.blue.accent-2{background-color:#448AFF!important}.blue-text.text-accent-2{color:#448AFF!important}.blue.accent-3{background-color:#2979FF!important}.blue-text.text-accent-3{color:#2979FF!important}.blue.accent-4{background-color:#2962FF!important}.blue-text.text-accent-4{color:#2962FF!important}.light-blue{background-color:#03a9f4!important}.light-blue-text{color:#03a9f4!important}.light-blue.lighten-5{background-color:#e1f5fe!important}.light-blue-text.text-lighten-5{color:#e1f5fe!important}.light-blue.lighten-4{background-color:#b3e5fc!important}.light-blue-text.text-lighten-4{color:#b3e5fc!important}.light-blue.lighten-3{background-color:#81d4fa!important}.light-blue-text.text-lighten-3{color:#81d4fa!important}.light-blue.lighten-2{background-color:#4fc3f7!important}.light-blue-text.text-lighten-2{color:#4fc3f7!important}.light-blue.lighten-1{background-color:#29b6f6!important}.light-blue-text.text-lighten-1{color:#29b6f6!important}.light-blue.darken-1{background-color:#039be5!important}.light-blue-text.text-darken-1{color:#039be5!important}.light-blue.darken-2{background-color:#0288d1!important}.light-blue-text.text-darken-2{color:#0288d1!important}.light-blue.darken-3{background-color:#0277bd!important}.light-blue-text.text-darken-3{color:#0277bd!important}.light-blue.darken-4{background-color:#01579b!important}.light-blue-text.text-darken-4{color:#01579b!important}.light-blue.accent-1{background-color:#80d8ff!important}.light-blue-text.text-accent-1{color:#80d8ff!important}.light-blue.accent-2{background-color:#40c4ff!important}.light-blue-text.text-accent-2{color:#40c4ff!important}.light-blue.accent-3{background-color:#00b0ff!important}.light-blue-text.text-accent-3{color:#00b0ff!important}.light-blue.accent-4{background-color:#0091ea!important}.light-blue-text.text-accent-4{color:#0091ea!important}.cyan{background-color:#00bcd4!important}.cyan-text{color:#00bcd4!important}.cyan.lighten-5{background-color:#e0f7fa!important}.cyan-text.text-lighten-5{color:#e0f7fa!important}.cyan.lighten-4{background-color:#b2ebf2!important}.cyan-text.text-lighten-4{color:#b2ebf2!important}.cyan.lighten-3{background-color:#80deea!important}.cyan-text.text-lighten-3{color:#80deea!important}.cyan.lighten-2{background-color:#4dd0e1!important}.cyan-text.text-lighten-2{color:#4dd0e1!important}.cyan.lighten-1{background-color:#26c6da!important}.cyan-text.text-lighten-1{color:#26c6da!important}.cyan.darken-1{background-color:#00acc1!important}.cyan-text.text-darken-1{color:#00acc1!important}.cyan.darken-2{background-color:#0097a7!important}.cyan-text.text-darken-2{color:#0097a7!important}.cyan.darken-3{background-color:#00838f!important}.cyan-text.text-darken-3{color:#00838f!important}.cyan.darken-4{background-color:#006064!important}.cyan-text.text-darken-4{color:#006064!important}.cyan.accent-1{background-color:#84ffff!important}.cyan-text.text-accent-1{color:#84ffff!important}.cyan.accent-2{background-color:#18ffff!important}.cyan-text.text-accent-2{color:#18ffff!important}.cyan.accent-3{background-color:#00e5ff!important}.cyan-text.text-accent-3{color:#00e5ff!important}.cyan.accent-4{background-color:#00b8d4!important}.cyan-text.text-accent-4{color:#00b8d4!important}.teal{background-color:#009688!important}.teal-text{color:#009688!important}.teal.lighten-5{background-color:#e0f2f1!important}.teal-text.text-lighten-5{color:#e0f2f1!important}.teal.lighten-4{background-color:#b2dfdb!important}.teal-text.text-lighten-4{color:#b2dfdb!important}.teal.lighten-3{background-color:#80cbc4!important}.teal-text.text-lighten-3{color:#80cbc4!important}.teal.lighten-2{background-color:#4db6ac!important}.teal-text.text-lighten-2{color:#4db6ac!important}.teal.lighten-1{background-color:#26a69a!important}.teal-text.text-lighten-1{color:#26a69a!important}.teal.darken-1{background-color:#00897b!important}.teal-text.text-darken-1{color:#00897b!important}.teal.darken-2{background-color:#00796b!important}.teal-text.text-darken-2{color:#00796b!important}.teal.darken-3{background-color:#00695c!important}.teal-text.text-darken-3{color:#00695c!important}.teal.darken-4{background-color:#004d40!important}.teal-text.text-darken-4{color:#004d40!important}.teal.accent-1{background-color:#a7ffeb!important}.teal-text.text-accent-1{color:#a7ffeb!important}.teal.accent-2{background-color:#64ffda!important}.teal-text.text-accent-2{color:#64ffda!important}.teal.accent-3{background-color:#1de9b6!important}.teal-text.text-accent-3{color:#1de9b6!important}.teal.accent-4{background-color:#00bfa5!important}.teal-text.text-accent-4{color:#00bfa5!important}.green{background-color:#4CAF50!important}.green-text{color:#4CAF50!important}.green.lighten-5{background-color:#E8F5E9!important}.green-text.text-lighten-5{color:#E8F5E9!important}.green.lighten-4{background-color:#C8E6C9!important}.green-text.text-lighten-4{color:#C8E6C9!important}.green.lighten-3{background-color:#A5D6A7!important}.green-text.text-lighten-3{color:#A5D6A7!important}.green.lighten-2{background-color:#81C784!important}.green-text.text-lighten-2{color:#81C784!important}.green.lighten-1{background-color:#66BB6A!important}.green-text.text-lighten-1{color:#66BB6A!important}.green.darken-1{background-color:#43A047!important}.green-text.text-darken-1{color:#43A047!important}.green.darken-2{background-color:#388E3C!important}.green-text.text-darken-2{color:#388E3C!important}.green.darken-3{background-color:#2E7D32!important}.green-text.text-darken-3{color:#2E7D32!important}.green.darken-4{background-color:#1B5E20!important}.green-text.text-darken-4{color:#1B5E20!important}.green.accent-1{background-color:#B9F6CA!important}.green-text.text-accent-1{color:#B9F6CA!important}.green.accent-2{background-color:#69F0AE!important}.green-text.text-accent-2{color:#69F0AE!important}.green.accent-3{background-color:#00E676!important}.green-text.text-accent-3{color:#00E676!important}.green.accent-4{background-color:#00C853!important}.green-text.text-accent-4{color:#00C853!important}.light-green{background-color:#8bc34a!important}.light-green-text{color:#8bc34a!important}.light-green.lighten-5{background-color:#f1f8e9!important}.light-green-text.text-lighten-5{color:#f1f8e9!important}.light-green.lighten-4{background-color:#dcedc8!important}.light-green-text.text-lighten-4{color:#dcedc8!important}.light-green.lighten-3{background-color:#c5e1a5!important}.light-green-text.text-lighten-3{color:#c5e1a5!important}.light-green.lighten-2{background-color:#aed581!important}.light-green-text.text-lighten-2{color:#aed581!important}.light-green.lighten-1{background-color:#9ccc65!important}.light-green-text.text-lighten-1{color:#9ccc65!important}.light-green.darken-1{background-color:#7cb342!important}.light-green-text.text-darken-1{color:#7cb342!important}.light-green.darken-2{background-color:#689f38!important}.light-green-text.text-darken-2{color:#689f38!important}.light-green.darken-3{background-color:#558b2f!important}.light-green-text.text-darken-3{color:#558b2f!important}.light-green.darken-4{background-color:#33691e!important}.light-green-text.text-darken-4{color:#33691e!important}.light-green.accent-1{background-color:#ccff90!important}.light-green-text.text-accent-1{color:#ccff90!important}.light-green.accent-2{background-color:#b2ff59!important}.light-green-text.text-accent-2{color:#b2ff59!important}.light-green.accent-3{background-color:#76ff03!important}.light-green-text.text-accent-3{color:#76ff03!important}.light-green.accent-4{background-color:#64dd17!important}.light-green-text.text-accent-4{color:#64dd17!important}.lime{background-color:#cddc39!important}.lime-text{color:#cddc39!important}.lime.lighten-5{background-color:#f9fbe7!important}.lime-text.text-lighten-5{color:#f9fbe7!important}.lime.lighten-4{background-color:#f0f4c3!important}.lime-text.text-lighten-4{color:#f0f4c3!important}.lime.lighten-3{background-color:#e6ee9c!important}.lime-text.text-lighten-3{color:#e6ee9c!important}.lime.lighten-2{background-color:#dce775!important}.lime-text.text-lighten-2{color:#dce775!important}.lime.lighten-1{background-color:#d4e157!important}.lime-text.text-lighten-1{color:#d4e157!important}.lime.darken-1{background-color:#c0ca33!important}.lime-text.text-darken-1{color:#c0ca33!important}.lime.darken-2{background-color:#afb42b!important}.lime-text.text-darken-2{color:#afb42b!important}.lime.darken-3{background-color:#9e9d24!important}.lime-text.text-darken-3{color:#9e9d24!important}.lime.darken-4{background-color:#827717!important}.lime-text.text-darken-4{color:#827717!important}.lime.accent-1{background-color:#f4ff81!important}.lime-text.text-accent-1{color:#f4ff81!important}.lime.accent-2{background-color:#eeff41!important}.lime-text.text-accent-2{color:#eeff41!important}.lime.accent-3{background-color:#c6ff00!important}.lime-text.text-accent-3{color:#c6ff00!important}.lime.accent-4{background-color:#aeea00!important}.lime-text.text-accent-4{color:#aeea00!important}.yellow{background-color:#ffeb3b!important}.yellow-text{color:#ffeb3b!important}.yellow.lighten-5{background-color:#fffde7!important}.yellow-text.text-lighten-5{color:#fffde7!important}.yellow.lighten-4{background-color:#fff9c4!important}.yellow-text.text-lighten-4{color:#fff9c4!important}.yellow.lighten-3{background-color:#fff59d!important}.yellow-text.text-lighten-3{color:#fff59d!important}.yellow.lighten-2{background-color:#fff176!important}.yellow-text.text-lighten-2{color:#fff176!important}.yellow.lighten-1{background-color:#ffee58!important}.yellow-text.text-lighten-1{color:#ffee58!important}.yellow.darken-1{background-color:#fdd835!important}.yellow-text.text-darken-1{color:#fdd835!important}.yellow.darken-2{background-color:#fbc02d!important}.yellow-text.text-darken-2{color:#fbc02d!important}.yellow.darken-3{background-color:#f9a825!important}.yellow-text.text-darken-3{color:#f9a825!important}.yellow.darken-4{background-color:#f57f17!important}.yellow-text.text-darken-4{color:#f57f17!important}.yellow.accent-1{background-color:#ffff8d!important}.yellow-text.text-accent-1{color:#ffff8d!important}.yellow.accent-2{background-color:#ff0!important}.yellow-text.text-accent-2{color:#ff0!important}.yellow.accent-3{background-color:#ffea00!important}.yellow-text.text-accent-3{color:#ffea00!important}.yellow.accent-4{background-color:#ffd600!important}.yellow-text.text-accent-4{color:#ffd600!important}.amber{background-color:#ffc107!important}.amber-text{color:#ffc107!important}.amber.lighten-5{background-color:#fff8e1!important}.amber-text.text-lighten-5{color:#fff8e1!important}.amber.lighten-4{background-color:#ffecb3!important}.amber-text.text-lighten-4{color:#ffecb3!important}.amber.lighten-3{background-color:#ffe082!important}.amber-text.text-lighten-3{color:#ffe082!important}.amber.lighten-2{background-color:#ffd54f!important}.amber-text.text-lighten-2{color:#ffd54f!important}.amber.lighten-1{background-color:#ffca28!important}.amber-text.text-lighten-1{color:#ffca28!important}.amber.darken-1{background-color:#ffb300!important}.amber-text.text-darken-1{color:#ffb300!important}.amber.darken-2{background-color:#ffa000!important}.amber-text.text-darken-2{color:#ffa000!important}.amber.darken-3{background-color:#ff8f00!important}.amber-text.text-darken-3{color:#ff8f00!important}.amber.darken-4{background-color:#ff6f00!important}.amber-text.text-darken-4{color:#ff6f00!important}.amber.accent-1{background-color:#ffe57f!important}.amber-text.text-accent-1{color:#ffe57f!important}.amber.accent-2{background-color:#ffd740!important}.amber-text.text-accent-2{color:#ffd740!important}.amber.accent-3{background-color:#ffc400!important}.amber-text.text-accent-3{color:#ffc400!important}.amber.accent-4{background-color:#ffab00!important}.amber-text.text-accent-4{color:#ffab00!important}.orange{background-color:#ff9800!important}.orange-text{color:#ff9800!important}.orange.lighten-5{background-color:#fff3e0!important}.orange-text.text-lighten-5{color:#fff3e0!important}.orange.lighten-4{background-color:#ffe0b2!important}.orange-text.text-lighten-4{color:#ffe0b2!important}.orange.lighten-3{background-color:#ffcc80!important}.orange-text.text-lighten-3{color:#ffcc80!important}.orange.lighten-2{background-color:#ffb74d!important}.orange-text.text-lighten-2{color:#ffb74d!important}.orange.lighten-1{background-color:#ffa726!important}.orange-text.text-lighten-1{color:#ffa726!important}.orange.darken-1{background-color:#fb8c00!important}.orange-text.text-darken-1{color:#fb8c00!important}.orange.darken-2{background-color:#f57c00!important}.orange-text.text-darken-2{color:#f57c00!important}.orange.darken-3{background-color:#ef6c00!important}.orange-text.text-darken-3{color:#ef6c00!important}.orange.darken-4{background-color:#e65100!important}.orange-text.text-darken-4{color:#e65100!important}.orange.accent-1{background-color:#ffd180!important}.orange-text.text-accent-1{color:#ffd180!important}.orange.accent-2{background-color:#ffab40!important}.orange-text.text-accent-2{color:#ffab40!important}.orange.accent-3{background-color:#ff9100!important}.orange-text.text-accent-3{color:#ff9100!important}.orange.accent-4{background-color:#ff6d00!important}.orange-text.text-accent-4{color:#ff6d00!important}.deep-orange{background-color:#ff5722!important}.deep-orange-text{color:#ff5722!important}.deep-orange.lighten-5{background-color:#fbe9e7!important}.deep-orange-text.text-lighten-5{color:#fbe9e7!important}.deep-orange.lighten-4{background-color:#ffccbc!important}.deep-orange-text.text-lighten-4{color:#ffccbc!important}.deep-orange.lighten-3{background-color:#ffab91!important}.deep-orange-text.text-lighten-3{color:#ffab91!important}.deep-orange.lighten-2{background-color:#ff8a65!important}.deep-orange-text.text-lighten-2{color:#ff8a65!important}.deep-orange.lighten-1{background-color:#ff7043!important}.deep-orange-text.text-lighten-1{color:#ff7043!important}.deep-orange.darken-1{background-color:#f4511e!important}.deep-orange-text.text-darken-1{color:#f4511e!important}.deep-orange.darken-2{background-color:#e64a19!important}.deep-orange-text.text-darken-2{color:#e64a19!important}.deep-orange.darken-3{background-color:#d84315!important}.deep-orange-text.text-darken-3{color:#d84315!important}.deep-orange.darken-4{background-color:#bf360c!important}.deep-orange-text.text-darken-4{color:#bf360c!important}.deep-orange.accent-1{background-color:#ff9e80!important}.deep-orange-text.text-accent-1{color:#ff9e80!important}.deep-orange.accent-2{background-color:#ff6e40!important}.deep-orange-text.text-accent-2{color:#ff6e40!important}.deep-orange.accent-3{background-color:#ff3d00!important}.deep-orange-text.text-accent-3{color:#ff3d00!important}.deep-orange.accent-4{background-color:#dd2c00!important}.deep-orange-text.text-accent-4{color:#dd2c00!important}.brown{background-color:#795548!important}.brown-text{color:#795548!important}.brown.lighten-5{background-color:#efebe9!important}.brown-text.text-lighten-5{color:#efebe9!important}.brown.lighten-4{background-color:#d7ccc8!important}.brown-text.text-lighten-4{color:#d7ccc8!important}.brown.lighten-3{background-color:#bcaaa4!important}.brown-text.text-lighten-3{color:#bcaaa4!important}.brown.lighten-2{background-color:#a1887f!important}.brown-text.text-lighten-2{color:#a1887f!important}.brown.lighten-1{background-color:#8d6e63!important}.brown-text.text-lighten-1{color:#8d6e63!important}.brown.darken-1{background-color:#6d4c41!important}.brown-text.text-darken-1{color:#6d4c41!important}.brown.darken-2{background-color:#5d4037!important}.brown-text.text-darken-2{color:#5d4037!important}.brown.darken-3{background-color:#4e342e!important}.brown-text.text-darken-3{color:#4e342e!important}.brown.darken-4{background-color:#3e2723!important}.brown-text.text-darken-4{color:#3e2723!important}.blue-grey{background-color:#607d8b!important}.blue-grey-text{color:#607d8b!important}.blue-grey.lighten-5{background-color:#eceff1!important}.blue-grey-text.text-lighten-5{color:#eceff1!important}.blue-grey.lighten-4{background-color:#cfd8dc!important}.blue-grey-text.text-lighten-4{color:#cfd8dc!important}.blue-grey.lighten-3{background-color:#b0bec5!important}.blue-grey-text.text-lighten-3{color:#b0bec5!important}.blue-grey.lighten-2{background-color:#90a4ae!important}.blue-grey-text.text-lighten-2{color:#90a4ae!important}.blue-grey.lighten-1{background-color:#78909c!important}.blue-grey-text.text-lighten-1{color:#78909c!important}.blue-grey.darken-1{background-color:#546e7a!important}.blue-grey-text.text-darken-1{color:#546e7a!important}.blue-grey.darken-2{background-color:#455a64!important}.blue-grey-text.text-darken-2{color:#455a64!important}.blue-grey.darken-3{background-color:#37474f!important}.blue-grey-text.text-darken-3{color:#37474f!important}.blue-grey.darken-4{background-color:#263238!important}.blue-grey-text.text-darken-4{color:#263238!important}.grey{background-color:#9e9e9e!important}.grey-text{color:#9e9e9e!important}.grey.lighten-5{background-color:#fafafa!important}.grey-text.text-lighten-5{color:#fafafa!important}.grey.lighten-4{background-color:#f5f5f5!important}.grey-text.text-lighten-4{color:#f5f5f5!important}.grey.lighten-3{background-color:#eee!important}.grey-text.text-lighten-3{color:#eee!important}.grey.lighten-2{background-color:#e0e0e0!important}.grey-text.text-lighten-2{color:#e0e0e0!important}.grey.lighten-1{background-color:#bdbdbd!important}.grey-text.text-lighten-1{color:#bdbdbd!important}.grey.darken-1{background-color:#757575!important}.grey-text.text-darken-1{color:#757575!important}.grey.darken-2{background-color:#616161!important}.grey-text.text-darken-2{color:#616161!important}.grey.darken-3{background-color:#424242!important}.grey-text.text-darken-3{color:#424242!important}.grey.darken-4{background-color:#212121!important}.grey-text.text-darken-4{color:#212121!important}.black{background-color:#000!important}.black-text{color:#000!important}.white{background-color:#FFF!important}.white-text{color:#FFF!important}.transparent{background-color:transparent!important}.transparent-text{color:transparent!important} + + + +body,p{color:#8a8a8a;font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif}.font-primary,body,p{font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif}label,ul{margin-bottom:0}dd,p{margin-bottom:10px}.m-h-0,.m-l-0{margin-left:0!important}.m-h-0,.m-r-0{margin-right:0!important}.p-t-0,.p-v-0{padding-top:0!important}.p-b-0,.p-v-0{padding-bottom:0!important}.p-h-0,.p-r-0{padding-right:0!important}.relative,blockquote{position:relative}.overflow-x-hidden,body{overflow-x:hidden}.header,.side-nav{transition:all .2s ease}.header .header-container:after,.side-nav .side-nav-inner .side-nav-menu:after{clear:both}.pointer,button{cursor:pointer}body,html,html a{-webkit-font-smoothing:antialiased}body{font-size:14px;background-color:#f7fbff;line-height:1.5}h1,h2,h3,h4,h5,h6{color:#515365;font-weight:400;line-height:1.5}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:300;color:#5c5f73}h1{font-size:28px}h2{font-size:24px}h3{font-size:22px}h4{font-size:19px}h5{font-size:17px}h6{font-size:12px}p{line-height:1.8}.lead{font-size:18px}a{color:#04a1f4}a:focus,a:hover{text-decoration:none;color:#0380c2}a:focus{outline:0}a.text-gray:focus,a.text-gray:hover{color:#515365!important}a.text-gray.active{color:#04a1f4!important}a.hover-opacity:hover{opacity:.8}:focus{outline:0}hr{border-top:1px solid #e9eaec;margin-top:2rem;margin-bottom:2rem}.text-link:focus,.text-link:hover{text-decoration:underline}.text-opacity{opacity:.85}.text-white{color:#fff!important}.text-dark{color:#515365!important}.text-gray{color:#8a8a8a!important}.text-secondary{color:#cacaca!important}.text-primary{color:#6569df!important}.text-success{color:#24d5d8!important}.text-info{color:#04a1f4!important}.text-warning{color:#fecd2f!important}.text-danger{color:#fd3259!important}.icon-gradient-primary{color:#6569df}.icon-gradient-primary:before{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-success{color:#24d5d8}.icon-gradient-success:before{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-warning{color:#fecd2f}.icon-gradient-warning:before{background:linear-gradient(120deg,#f6d365 0,#fda085 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-danger{color:#fd3259}.icon-gradient-danger:before{background:linear-gradient(120deg,#f3301a 0,#f37138 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-info{color:#04a1f4}.blockquote-footer,.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a,.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,dt{color:#515365}.icon-gradient-info:before{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.bg-white{background-color:#fff!important}.bg-dark{background-color:#515365!important}.bg-gray{background-color:#fafafa!important}.bg-primary{background-color:#6569df!important}.bg-success{background-color:#24d5d8!important}.bg-info{background-color:#04a1f4!important}.bg-warning{background-color:#fecd2f!important}.bg-danger{background-color:#fd3259!important}.bg-gradient-primary{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)!important}.bg-gradient-success{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)!important}.bg-gradient-info{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)!important}.bg-gradient-warning{background:linear-gradient(120deg,#f6d365 0,#fda085 100%)!important}.bg-gradient-danger{background:linear-gradient(120deg,#f3301a 0,#f37138 100%)!important}.bg-facebook{background-color:#3B579D!important}.bg-twitter{background-color:#2CAAE1!important}.bg-google-plus{background-color:#dc473c!important}.bg-instagram{background-color:#40719b!important}.bg-dropbox{background-color:#007EE6!important}.bg-dribbble{background-color:#ea4c89!important}.bg-behance{background-color:#1869ff!important}.bg-html5{background-color:#f16528!important}.bg-wordpress{background-color:#0087be!important}.bg-tumblr{background-color:#36465d!important}.bg-skype{background-color:#00AAF1!important}.bg-youtube{background-color:#DE2825!important}.bg-vimeo{background-color:#1BB6EC!important}.bg-linkedin{background-color:#0177b5!important}.bg-pinterest{background-color:#c9181f!important}.img-fit-cover{width:100%;height:100%;object-fit:cover}.bg{background-repeat:no-repeat;background-size:cover;background-position:center center}.container-fluid.container-fixed-lg{max-width:1700px}.container-fluid.container-fixed-md{max-width:1400px}.container-fluid.container-fixed-sm{max-width:1280px}button,input,textarea{outline:0}blockquote{border-left:0;padding-left:30px}.p-h-0,.p-l-0{padding-left:0!important}dt{font-weight:500}.m-b-0,.m-v-0{margin-bottom:0!important}.fade.in{opacity:1}.collapse.in{display:block}iframe{border:0}@media print{body{font-size:10px}.mrg-top-20,.mrg-top-30{margin-top:15px!important}.print-invisible{display:none}}.m-t-0,.m-v-0{margin-top:0!important}.m-0{margin:0!important}.m-5{margin:5px!important}.m-10{margin:10px!important}.m-15{margin:15px!important}.m-20{margin:20px!important}.m-25{margin:25px!important}.m-30{margin:30px!important}.m-35{margin:35px!important}.m-40{margin:40px!important}.m-45{margin:45px!important}.m-50{margin:50px!important}.m-55{margin:55px!important}.m-60{margin:60px!important}.m-65{margin:65px!important}.m-70{margin:70px!important}.m-75{margin:75px!important}.m-80{margin:80px!important}.m-85{margin:85px!important}.m-90{margin:90px!important}.m-95{margin:95px!important}.m-100{margin:100px!important}.m-105{margin:105px!important}.m-110{margin:110px!important}.m-115{margin:115px!important}.m-120{margin:120px!important}.m-125{margin:125px!important}.m-130{margin:130px!important}.m-135{margin:135px!important}.m-140{margin:140px!important}.m-145{margin:145px!important}.m-150{margin:150px!important}@media only screen and (max-width:767px){iframe{min-height:175px!important;height:auto}.m-100,.m-110,.m-115,.m-120,.m-125,.m-130,.m-135,.m-140,.m-145,.m-150,.m-35,.m-40,.m-45,.m-50,.m-55,.m-60,.m-65,.m-70,.m-75,.m-80,.m-85,.m-90,.m-95{margin:30px!important}}.m-h-auto,.m-l-auto{margin-left:auto!important}.m-h-auto,.m-r-auto{margin-right:auto!important}.m-v-5{margin-top:5px!important;margin-bottom:5px!important}.m-v-10{margin-top:10px!important;margin-bottom:10px!important}.m-v-15{margin-top:15px!important;margin-bottom:15px!important}.m-v-20{margin-top:20px!important;margin-bottom:20px!important}.m-v-25{margin-top:25px!important;margin-bottom:25px!important}.m-v-30{margin-top:30px!important;margin-bottom:30px!important}.m-v-35{margin-top:35px!important;margin-bottom:35px!important}.m-v-40{margin-top:40px!important;margin-bottom:40px!important}.m-v-45{margin-top:45px!important;margin-bottom:45px!important}.m-v-50{margin-top:50px!important;margin-bottom:50px!important}.m-v-55{margin-top:55px!important;margin-bottom:55px!important}.m-v-60{margin-top:60px!important;margin-bottom:60px!important}.m-v-65{margin-top:65px!important;margin-bottom:65px!important}.m-v-70{margin-top:70px!important;margin-bottom:70px!important}.m-v-75{margin-top:75px!important;margin-bottom:75px!important}.m-v-80{margin-top:80px!important;margin-bottom:80px!important}.m-v-85{margin-top:85px!important;margin-bottom:85px!important}.m-v-90{margin-top:90px!important;margin-bottom:90px!important}.m-v-95{margin-top:95px!important;margin-bottom:95px!important}.m-v-100{margin-top:100px!important;margin-bottom:100px!important}.m-v-105{margin-top:105px!important;margin-bottom:105px!important}.m-v-110{margin-top:110px!important;margin-bottom:110px!important}.m-v-115{margin-top:115px!important;margin-bottom:115px!important}.m-v-120{margin-top:120px!important;margin-bottom:120px!important}.m-v-125{margin-top:125px!important;margin-bottom:125px!important}.m-v-130{margin-top:130px!important;margin-bottom:130px!important}.m-v-135{margin-top:135px!important;margin-bottom:135px!important}.m-v-140{margin-top:140px!important;margin-bottom:140px!important}.m-v-145{margin-top:145px!important;margin-bottom:145px!important}.m-v-150{margin-top:150px!important;margin-bottom:150px!important}.m-h-5{margin-left:5px!important;margin-right:5px!important}.m-h-10{margin-left:10px!important;margin-right:10px!important}.m-h-15{margin-left:15px!important;margin-right:15px!important}.m-h-20{margin-left:20px!important;margin-right:20px!important}.m-h-25{margin-left:25px!important;margin-right:25px!important}.m-h-30{margin-left:30px!important;margin-right:30px!important}.m-h-35{margin-left:35px!important;margin-right:35px!important}.m-h-40{margin-left:40px!important;margin-right:40px!important}.m-h-45{margin-left:45px!important;margin-right:45px!important}.m-h-50{margin-left:50px!important;margin-right:50px!important}.m-h-55{margin-left:55px!important;margin-right:55px!important}.m-h-60{margin-left:60px!important;margin-right:60px!important}.m-h-65{margin-left:65px!important;margin-right:65px!important}.m-h-70{margin-left:70px!important;margin-right:70px!important}.m-h-75{margin-left:75px!important;margin-right:75px!important}.m-h-80{margin-left:80px!important;margin-right:80px!important}.m-h-85{margin-left:85px!important;margin-right:85px!important}.m-h-90{margin-left:90px!important;margin-right:90px!important}.m-h-95{margin-left:95px!important;margin-right:95px!important}.m-h-100{margin-left:100px!important;margin-right:100px!important}.m-h-105{margin-left:105px!important;margin-right:105px!important}.m-h-110{margin-left:110px!important;margin-right:110px!important}.m-h-115{margin-left:115px!important;margin-right:115px!important}.m-h-120{margin-left:120px!important;margin-right:120px!important}.m-h-125{margin-left:125px!important;margin-right:125px!important}.m-h-130{margin-left:130px!important;margin-right:130px!important}.m-h-135{margin-left:135px!important;margin-right:135px!important}.m-h-140{margin-left:140px!important;margin-right:140px!important}.m-h-145{margin-left:145px!important;margin-right:145px!important}.m-h-150{margin-left:150px!important;margin-right:150px!important}@media only screen and (max-width:767px){.m-v-100,.m-v-110,.m-v-115,.m-v-120,.m-v-125,.m-v-130,.m-v-135,.m-v-140,.m-v-145,.m-v-150,.m-v-35,.m-v-40,.m-v-45,.m-v-50,.m-v-55,.m-v-60,.m-v-65,.m-v-70,.m-v-75,.m-v-80,.m-v-85,.m-v-90,.m-v-95{margin-top:30px!important;margin-bottom:30px!important}.m-h-100,.m-h-110,.m-h-115,.m-h-120,.m-h-125,.m-h-130,.m-h-135,.m-h-140,.m-h-145,.m-h-150,.m-h-35,.m-h-40,.m-h-45,.m-h-50,.m-h-55,.m-h-60,.m-h-65,.m-h-70,.m-h-75,.m-h-80,.m-h-85,.m-h-90,.m-h-95{margin-left:30px!important;margin-right:30px!important}}.m-t-5{margin-top:5px!important}.m-t-10{margin-top:10px!important}.m-t-15{margin-top:15px!important}.m-t-20{margin-top:20px!important}.m-t-25{margin-top:25px!important}.m-t-30{margin-top:30px!important}.m-t-35{margin-top:35px!important}.m-t-40{margin-top:40px!important}.m-t-45{margin-top:45px!important}.m-t-50{margin-top:50px!important}.m-t-55{margin-top:55px!important}.m-t-60{margin-top:60px!important}.m-t-65{margin-top:65px!important}.m-t-70{margin-top:70px!important}.m-t-75{margin-top:75px!important}.m-t-80{margin-top:80px!important}.m-t-85{margin-top:85px!important}.m-t-90{margin-top:90px!important}.m-t-95{margin-top:95px!important}.m-t-100{margin-top:100px!important}.m-t-105{margin-top:105px!important}.m-t-110{margin-top:110px!important}.m-t-115{margin-top:115px!important}.m-t-120{margin-top:120px!important}.m-t-125{margin-top:125px!important}.m-t-130{margin-top:130px!important}.m-t-135{margin-top:135px!important}.m-t-140{margin-top:140px!important}.m-t-145{margin-top:145px!important}.m-t-150{margin-top:150px!important}.m-b-5{margin-bottom:5px!important}.m-b-10{margin-bottom:10px!important}.m-b-15{margin-bottom:15px!important}.m-b-20{margin-bottom:20px!important}.m-b-25{margin-bottom:25px!important}.m-b-30{margin-bottom:30px!important}.m-b-35{margin-bottom:35px!important}.m-b-40{margin-bottom:40px!important}.m-b-45{margin-bottom:45px!important}.m-b-50{margin-bottom:50px!important}.m-b-55{margin-bottom:55px!important}.m-b-60{margin-bottom:60px!important}.m-b-65{margin-bottom:65px!important}.m-b-70{margin-bottom:70px!important}.m-b-75{margin-bottom:75px!important}.m-b-80{margin-bottom:80px!important}.m-b-85{margin-bottom:85px!important}.m-b-90{margin-bottom:90px!important}.m-b-95{margin-bottom:95px!important}.m-b-100{margin-bottom:100px!important}.m-b-105{margin-bottom:105px!important}.m-b-110{margin-bottom:110px!important}.m-b-115{margin-bottom:115px!important}.m-b-120{margin-bottom:120px!important}.m-b-125{margin-bottom:125px!important}.m-b-130{margin-bottom:130px!important}.m-b-135{margin-bottom:135px!important}.m-b-140{margin-bottom:140px!important}.m-b-145{margin-bottom:145px!important}.m-b-150{margin-bottom:150px!important}.m-l-5{margin-left:5px!important}.m-l-10{margin-left:10px!important}.m-l-15{margin-left:15px!important}.m-l-20{margin-left:20px!important}.m-l-25{margin-left:25px!important}.m-l-30{margin-left:30px!important}.m-l-35{margin-left:35px!important}.m-l-40{margin-left:40px!important}.m-l-45{margin-left:45px!important}.m-l-50{margin-left:50px!important}.m-l-55{margin-left:55px!important}.m-l-60{margin-left:60px!important}.m-l-65{margin-left:65px!important}.m-l-70{margin-left:70px!important}.m-l-75{margin-left:75px!important}.m-l-80{margin-left:80px!important}.m-l-85{margin-left:85px!important}.m-l-90{margin-left:90px!important}.m-l-95{margin-left:95px!important}.m-l-100{margin-left:100px!important}.m-l-105{margin-left:105px!important}.m-l-110{margin-left:110px!important}.m-l-115{margin-left:115px!important}.m-l-120{margin-left:120px!important}.m-l-125{margin-left:125px!important}.m-l-130{margin-left:130px!important}.m-l-135{margin-left:135px!important}.m-l-140{margin-left:140px!important}.m-l-145{margin-left:145px!important}.m-l-150{margin-left:150px!important}.m-r-5{margin-right:5px!important}.m-r-10{margin-right:10px!important}.m-r-15{margin-right:15px!important}.m-r-20{margin-right:20px!important}.m-r-25{margin-right:25px!important}.m-r-30{margin-right:30px!important}.m-r-35{margin-right:35px!important}.m-r-40{margin-right:40px!important}.m-r-45{margin-right:45px!important}.m-r-50{margin-right:50px!important}.m-r-55{margin-right:55px!important}.m-r-60{margin-right:60px!important}.m-r-65{margin-right:65px!important}.m-r-70{margin-right:70px!important}.m-r-75{margin-right:75px!important}.m-r-80{margin-right:80px!important}.m-r-85{margin-right:85px!important}.m-r-90{margin-right:90px!important}.m-r-95{margin-right:95px!important}.m-r-100{margin-right:100px!important}.m-r-105{margin-right:105px!important}.m-r-110{margin-right:110px!important}.m-r-115{margin-right:115px!important}.m-r-120{margin-right:120px!important}.m-r-125{margin-right:125px!important}.m-r-130{margin-right:130px!important}.m-r-135{margin-right:135px!important}.m-r-140{margin-right:140px!important}.m-r-145{margin-right:145px!important}.m-r-150{margin-right:150px!important}.p-0{padding:0!important}.p-5{padding:5px!important}.p-10{padding:10px!important}.p-15{padding:15px!important}.p-20{padding:20px!important}.p-25{padding:25px!important}.p-30{padding:30px!important}.p-35{padding:35px!important}.p-40{padding:40px!important}.p-45{padding:45px!important}.p-50{padding:50px!important}.p-55{padding:55px!important}.p-60{padding:60px!important}.p-65{padding:65px!important}.p-70{padding:70px!important}.p-75{padding:75px!important}.p-80{padding:80px!important}.p-85{padding:85px!important}.p-90{padding:90px!important}.p-95{padding:95px!important}.p-100{padding:100px!important}.p-105{padding:105px!important}.p-110{padding:110px!important}.p-115{padding:115px!important}.p-120{padding:120px!important}.p-125{padding:125px!important}.p-130{padding:130px!important}.p-135{padding:135px!important}.p-140{padding:140px!important}.p-145{padding:145px!important}.p-150{padding:150px!important}@media only screen and (max-width:767px){.m-t-100,.m-t-110,.m-t-115,.m-t-120,.m-t-125,.m-t-130,.m-t-135,.m-t-140,.m-t-145,.m-t-150,.m-t-35,.m-t-40,.m-t-45,.m-t-50,.m-t-55,.m-t-60,.m-t-65,.m-t-70,.m-t-75,.m-t-80,.m-t-85,.m-t-90,.m-t-95{margin-top:30px!important}.m-b-100,.m-b-110,.m-b-115,.m-b-120,.m-b-125,.m-b-130,.m-b-135,.m-b-140,.m-b-145,.m-b-150,.m-b-35,.m-b-40,.m-b-45,.m-b-50,.m-b-55,.m-b-60,.m-b-65,.m-b-70,.m-b-75,.m-b-80,.m-b-85,.m-b-90,.m-b-95{margin-bottom:30px!important}.m-l-100,.m-l-110,.m-l-115,.m-l-120,.m-l-125,.m-l-130,.m-l-135,.m-l-140,.m-l-145,.m-l-150,.m-l-35,.m-l-40,.m-l-45,.m-l-50,.m-l-55,.m-l-60,.m-l-65,.m-l-70,.m-l-75,.m-l-80,.m-l-85,.m-l-90,.m-l-95{margin-left:30px!important}.m-r-100,.m-r-110,.m-r-115,.m-r-120,.m-r-125,.m-r-130,.m-r-135,.m-r-140,.m-r-145,.m-r-150,.m-r-35,.m-r-40,.m-r-45,.m-r-50,.m-r-55,.m-r-60,.m-r-65,.m-r-70,.m-r-75,.m-r-80,.m-r-85,.m-r-90,.m-r-95{margin-right:30px!important}.p-100,.p-110,.p-115,.p-120,.p-125,.p-130,.p-135,.p-140,.p-145,.p-150,.p-35,.p-40,.p-45,.p-50,.p-55,.p-60,.p-65,.p-70,.p-75,.p-80,.p-85,.p-90,.p-95{padding:30px!important}}.p-v-5{padding-top:5px!important;padding-bottom:5px!important}.p-v-10{padding-top:10px!important;padding-bottom:10px!important}.p-v-15{padding-top:15px!important;padding-bottom:15px!important}.p-v-20{padding-top:20px!important;padding-bottom:20px!important}.p-v-25{padding-top:25px!important;padding-bottom:25px!important}.p-v-30{padding-top:30px!important;padding-bottom:30px!important}.p-v-35{padding-top:35px!important;padding-bottom:35px!important}.p-v-40{padding-top:40px!important;padding-bottom:40px!important}.p-v-45{padding-top:45px!important;padding-bottom:45px!important}.p-v-50{padding-top:50px!important;padding-bottom:50px!important}.p-v-55{padding-top:55px!important;padding-bottom:55px!important}.p-v-60{padding-top:60px!important;padding-bottom:60px!important}.p-v-65{padding-top:65px!important;padding-bottom:65px!important}.p-v-70{padding-top:70px!important;padding-bottom:70px!important}.p-v-75{padding-top:75px!important;padding-bottom:75px!important}.p-v-80{padding-top:80px!important;padding-bottom:80px!important}.p-v-85{padding-top:85px!important;padding-bottom:85px!important}.p-v-90{padding-top:90px!important;padding-bottom:90px!important}.p-v-95{padding-top:95px!important;padding-bottom:95px!important}.p-v-100{padding-top:100px!important;padding-bottom:100px!important}.p-v-105{padding-top:105px!important;padding-bottom:105px!important}.p-v-110{padding-top:110px!important;padding-bottom:110px!important}.p-v-115{padding-top:115px!important;padding-bottom:115px!important}.p-v-120{padding-top:120px!important;padding-bottom:120px!important}.p-v-125{padding-top:125px!important;padding-bottom:125px!important}.p-v-130{padding-top:130px!important;padding-bottom:130px!important}.p-v-135{padding-top:135px!important;padding-bottom:135px!important}.p-v-140{padding-top:140px!important;padding-bottom:140px!important}.p-v-145{padding-top:145px!important;padding-bottom:145px!important}.p-v-150{padding-top:150px!important;padding-bottom:150px!important}.p-h-5{padding-left:5px!important;padding-right:5px!important}.p-h-10{padding-left:10px!important;padding-right:10px!important}.p-h-15{padding-left:15px!important;padding-right:15px!important}.p-h-20{padding-left:20px!important;padding-right:20px!important}.p-h-25{padding-left:25px!important;padding-right:25px!important}.p-h-30{padding-left:30px!important;padding-right:30px!important}.p-h-35{padding-left:35px!important;padding-right:35px!important}.p-h-40{padding-left:40px!important;padding-right:40px!important}.p-h-45{padding-left:45px!important;padding-right:45px!important}.p-h-50{padding-left:50px!important;padding-right:50px!important}.p-h-55{padding-left:55px!important;padding-right:55px!important}.p-h-60{padding-left:60px!important;padding-right:60px!important}.p-h-65{padding-left:65px!important;padding-right:65px!important}.p-h-70{padding-left:70px!important;padding-right:70px!important}.p-h-75{padding-left:75px!important;padding-right:75px!important}.p-h-80{padding-left:80px!important;padding-right:80px!important}.p-h-85{padding-left:85px!important;padding-right:85px!important}.p-h-90{padding-left:90px!important;padding-right:90px!important}.p-h-95{padding-left:95px!important;padding-right:95px!important}.p-h-100{padding-left:100px!important;padding-right:100px!important}.p-h-105{padding-left:105px!important;padding-right:105px!important}.p-h-110{padding-left:110px!important;padding-right:110px!important}.p-h-115{padding-left:115px!important;padding-right:115px!important}.p-h-120{padding-left:120px!important;padding-right:120px!important}.p-h-125{padding-left:125px!important;padding-right:125px!important}.p-h-130{padding-left:130px!important;padding-right:130px!important}.p-h-135{padding-left:135px!important;padding-right:135px!important}.p-h-140{padding-left:140px!important;padding-right:140px!important}.p-h-145{padding-left:145px!important;padding-right:145px!important}.p-h-150{padding-left:150px!important;padding-right:150px!important}@media only screen and (max-width:767px){.p-v-100,.p-v-110,.p-v-115,.p-v-120,.p-v-125,.p-v-130,.p-v-135,.p-v-140,.p-v-145,.p-v-150,.p-v-35,.p-v-40,.p-v-45,.p-v-50,.p-v-55,.p-v-60,.p-v-65,.p-v-70,.p-v-75,.p-v-80,.p-v-85,.p-v-90,.p-v-95{padding-top:30px!important;padding-bottom:30px!important}.p-h-100,.p-h-110,.p-h-115,.p-h-120,.p-h-125,.p-h-130,.p-h-135,.p-h-140,.p-h-145,.p-h-150,.p-h-35,.p-h-40,.p-h-45,.p-h-50,.p-h-55,.p-h-60,.p-h-65,.p-h-70,.p-h-75,.p-h-80,.p-h-85,.p-h-90,.p-h-95{padding-left:30px!important;padding-right:30px!important}}.p-t-5{padding-top:5px!important}.p-t-10{padding-top:10px!important}.p-t-15{padding-top:15px!important}.p-t-20{padding-top:20px!important}.p-t-25{padding-top:25px!important}.p-t-30{padding-top:30px!important}.p-t-35{padding-top:35px!important}.p-t-40{padding-top:40px!important}.p-t-45{padding-top:45px!important}.p-t-50{padding-top:50px!important}.p-t-55{margin-top:55px!important}.p-t-60{padding-top:60px!important}.p-t-65{padding-top:65px!important}.p-t-70{padding-top:70px!important}.p-t-75{padding-top:75px!important}.p-t-80{padding-top:80px!important}.p-t-85{padding-top:85px!important}.p-t-90{padding-top:90px!important}.p-t-95{padding-top:95px!important}.p-t-100{padding-top:100px!important}.p-t-105{padding-top:105px!important}.p-t-110{padding-top:110px!important}.p-t-115{padding-top:115px!important}.p-t-120{padding-top:120px!important}.p-t-125{padding-top:125px!important}.p-t-130{padding-top:130px!important}.p-t-135{padding-top:135px!important}.p-t-140{padding-top:140px!important}.p-t-145{padding-top:145px!important}.p-t-150{padding-top:150px!important}.p-b-5{padding-bottom:5px!important}.p-b-10{padding-bottom:10px!important}.p-b-15{padding-bottom:15px!important}.p-b-20{padding-bottom:20px!important}.p-b-25{padding-bottom:25px!important}.p-b-30{padding-bottom:30px!important}.p-b-35{padding-bottom:35px!important}.p-b-40{padding-bottom:40px!important}.p-b-45{padding-bottom:45px!important}.p-b-50{padding-bottom:50px!important}.p-b-55{margin-bottom:55px!important}.p-b-60{padding-bottom:60px!important}.p-b-65{padding-bottom:65px!important}.p-b-70{padding-bottom:70px!important}.p-b-75{padding-bottom:75px!important}.p-b-80{padding-bottom:80px!important}.p-b-85{padding-bottom:85px!important}.p-b-90{padding-bottom:90px!important}.p-b-95{padding-bottom:95px!important}.p-b-100{padding-bottom:100px!important}.p-b-105{padding-bottom:105px!important}.p-b-110{padding-bottom:110px!important}.p-b-115{padding-bottom:115px!important}.p-b-120{margin-bottom:120px!important}.p-b-125{padding-bottom:125px!important}.p-b-130{padding-bottom:130px!important}.p-b-135{padding-bottom:135px!important}.p-b-140{padding-bottom:140px!important}.p-b-145{padding-bottom:145px!important}.p-b-150{padding-bottom:150px!important}.p-l-5{padding-left:5px!important}.p-l-10{padding-left:10px!important}.p-l-15{padding-left:15px!important}.p-l-20{padding-left:20px!important}.p-l-25{padding-left:25px!important}.p-l-30{padding-left:30px!important}.p-l-35{padding-left:35px!important}.p-l-40{padding-left:40px!important}.p-l-45{padding-left:45px!important}.p-l-50{padding-left:50px!important}.p-l-55{margin-left:55px!important}.p-l-60{padding-left:60px!important}.p-l-65{padding-left:65px!important}.p-l-70{padding-left:70px!important}.p-l-75{padding-left:75px!important}.p-l-80{padding-left:80px!important}.p-l-85{padding-left:85px!important}.p-l-90{padding-left:90px!important}.p-l-95{padding-left:95px!important}.p-l-100{padding-left:100px!important}.p-l-105{padding-left:105px!important}.p-l-115{padding-left:115px!important}.p-l-120{margin-left:120px!important}.p-l-125{padding-left:125px!important}.p-l-130{padding-left:130px!important}.p-l-135{padding-left:135px!important}.p-l-140{padding-left:140px!important}.p-l-145{padding-left:145px!important}.p-l-150{padding-left:150px!important}@media only screen and (max-width:767px){.p-t-100,.p-t-110,.p-t-115,.p-t-120,.p-t-125,.p-t-130,.p-t-135,.p-t-140,.p-t-145,.p-t-150,.p-t-35,.p-t-40,.p-t-45,.p-t-50,.p-t-55,.p-t-60,.p-t-65,.p-t-70,.p-t-75,.p-t-80,.p-t-85,.p-t-90,.p-t-95{padding-top:30px!important}.p-b-100,.p-b-110,.p-b-115,.p-b-120,.p-b-125,.p-b-130,.p-b-135,.p-b-140,.p-b-145,.p-b-150,.p-b-35,.p-b-40,.p-b-45,.p-b-50,.p-b-55,.p-b-60,.p-b-65,.p-b-70,.p-b-75,.p-b-80,.p-b-85,.p-b-90,.p-b-95{padding-bottom:30px!important}.p-l-100,.p-l-110,.p-l-115,.p-l-120,.p-l-125,.p-l-130,.p-l-135,.p-l-140,.p-l-145,.p-l-150,.p-l-35,.p-l-40,.p-l-45,.p-l-50,.p-l-55,.p-l-60,.p-l-65,.p-l-70,.p-l-75,.p-l-80,.p-l-85,.p-l-90,.p-l-95{padding-left:30px!important}}.p-r-5{padding-right:5px!important}.p-r-10{padding-right:10px!important}.p-r-15{padding-right:15px!important}.p-r-20{padding-right:20px!important}.p-r-25{padding-right:25px!important}.p-r-30{padding-right:30px!important}.p-r-35{padding-right:35px!important}.p-r-40{padding-right:40px!important}.p-r-45{padding-right:45px!important}.p-r-50{padding-right:50px!important}.p-r-55{margin-right:55px!important}.p-r-60{padding-right:60px!important}.p-r-65{padding-right:65px!important}.p-r-70{padding-right:70px!important}.p-r-75{padding-right:75px!important}.p-r-80{padding-right:80px!important}.p-r-85{padding-right:85px!important}.p-r-90{padding-right:90px!important}.p-r-95{padding-right:95px!important}.p-r-100{padding-right:100px!important}.p-r-105{padding-right:105px!important}.p-l-110{padding-left:110px!important}.p-r-115{padding-right:115px!important}.p-r-120{margin-right:120px!important}.p-r-125{padding-right:125px!important}.p-r-130{padding-right:130px!important}.p-r-135{padding-right:135px!important}.p-r-140{padding-right:140px!important}.p-r-145{padding-right:145px!important}.p-r-150{padding-right:150px!important}.width-0{width:0}.width-10{width:10%}.width-15{width:15%}.width-20{width:20%}.width-25{width:25%}.width-30{width:30%}.width-35{width:35%}.width-40{width:40%}.width-45{width:45%}.width-50{width:50%}.width-55{width:55%}.width-60{width:60%}.width-65{width:65%}.width-70{width:70%}.width-75{width:75%}.width-80{width:80%}.width-85{width:85%}.width-90{width:90%}.width-95{width:95%}.width-100{width:100%}.height-max{height:100%}.full-height{min-height:100vh}.ls-0{letter-spacing:0!important}.ls-0-5{letter-spacing:.5px!important}.ls-1{letter-spacing:1px!important}.ls-1-5{letter-spacing:1.5px!important}.ls-2{letter-spacing:2px!important}.ls-2-5{letter-spacing:2.5px!important}.ls-3{letter-spacing:3px!important}.ls-3-5{letter-spacing:3.5px!important}.ls-4{letter-spacing:4px!important}.ls-4-5{letter-spacing:4.5px!important}.ls-5{letter-spacing:5px!important}.ls-5-5{letter-spacing:5.5px!important}.ls-6{letter-spacing:6px!important}.ls-6-5{letter-spacing:6.5px!important}.ls-7{letter-spacing:7px!important}.ls-7-5{letter-spacing:7.5px!important}.ls-8{letter-spacing:8px!important}.ls-8-5{letter-spacing:8.5px!important}.ls-9{letter-spacing:9px!important}.ls-9-5{letter-spacing:9.5px!important}.ls-10{letter-spacing:10px!important}.ls-11{letter-spacing:11px!important}.ls-12{letter-spacing:12px!important}.ls-13{letter-spacing:13px!important}.ls-14{letter-spacing:14px!important}.ls-15{letter-spacing:15px!important}.lh-0{line-height:0!important}.lh-0-5{line-height:.5!important}.lh-1{line-height:1!important}.lh-1-1{line-height:1.1!important}.lh-1-2{line-height:1.2!important}.lh-1-3{line-height:1.3!important}.lh-1-4{line-height:1.4!important}.lh-1-5{line-height:1.5!important}.lh-1-6{line-height:1.6!important}.lh-1-7{line-height:1.7!important}.lh-1-8{line-height:1.8!important}.lh-1-9{line-height:1.9!important}.lh-2{line-height:2!important}.lh-2-1{line-height:2.1!important}.lh-2-2{line-height:2.2!important}.lh-2-3{line-height:2.3!important}.lh-2-4{line-height:2.4!important}.lh-2-5{line-height:2.5!important}.lh-3{line-height:3!important}.lh-4{line-height:4!important}.font-size-8{font-size:8px!important}.font-size-9{font-size:9px!important}.font-size-10{font-size:10px!important}.font-size-11{font-size:11px!important}.font-size-12{font-size:12px!important}.font-size-13{font-size:13px!important}.font-size-14{font-size:14px!important}.font-size-15{font-size:15px!important}.font-size-16{font-size:16px!important}.font-size-17{font-size:17px!important}.font-size-18{font-size:18px!important}.font-size-19{font-size:19px!important}.font-size-20{font-size:20px!important}.font-size-21{font-size:21px!important}.font-size-22{font-size:22px!important}.font-size-23{font-size:23px!important}.font-size-24{font-size:24px!important}.font-size-25{font-size:25px!important}.font-size-26{font-size:26px!important}.font-size-27{font-size:27px!important}.font-size-28{font-size:28px!important}.font-size-29{font-size:29px!important}.font-size-30{font-size:30px!important}.font-size-35{font-size:35px!important}.font-size-40{font-size:40px!important}.font-size-45{font-size:45px!important}.font-size-50{font-size:50px!important}.font-size-55{font-size:55px!important}.font-size-60{font-size:60px!important}.font-size-65{font-size:65px!important}.font-size-70{font-size:70px!important}.font-size-75{font-size:75px!important}.font-size-80{font-size:80px!important}.font-size-85{font-size:85px!important}.font-size-90{font-size:90px!important}.font-size-95{font-size:95px!important}.font-size-100{font-size:100px!important}.font-size-105{font-size:105px!important}.font-size-110{font-size:110px!important}.font-size-115{font-size:115px!important}.font-size-120{font-size:120px!important}.font-size-125{font-size:125px!important}.font-size-130{font-size:130px!important}.font-size-135{font-size:135px!important}.font-size-140{font-size:140px!important}.font-size-145{font-size:145px!important}.font-size-150{font-size:150px!important}.font-size-155{font-size:155px!important}.font-size-160{font-size:160px!important}.font-size-165{font-size:165px!important}.font-size-170{font-size:170px!important}.font-size-175{font-size:175px!important}.font-size-180{font-size:180px!important}.font-size-185{font-size:185px!important}.font-size-190{font-size:190px!important}.font-size-195{font-size:195px!important}.font-size-200{font-size:200px!important}.text-thin{font-weight:300!important}.text-normal{font-weight:400!important}.text-semibold{font-weight:500!important}.text-bold{font-weight:700!important}.display-block{display:block!important}.inline-block{display:inline-block!important}.absolute{position:absolute}.fixed{position:fixed}.static{position:static}.overflow-hidden{overflow:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-auto{overflow:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-auto{overflow-x:auto}.img-circle{border-radius:50%!important}.border{border:1px solid #e9eaec}.border.top{border:0!important;border-top:1px solid #e9eaec!important}.border.right{border:0!important;border-right:1px solid #e9eaec!important}.border.bottom{border:0!important;border-bottom:1px solid #e9eaec!important}.border.left{border:0!important;border-left:1px solid #e9eaec!important}@media only screen and (max-width:992px){.border.border-hide-md{border-top:0!important;border-right:0!important;border-bottom:0!important;border-left:0!important}}.no-border{border:0!important;border-radius:0!important}.rounded{border-radius:8px!important}.vertical-align{display:table;height:100%;width:100%}.vertical-align .table-cell{display:table-cell;vertical-align:middle}.vertical-align-super{vertical-align:super}.border-radius-4{border-radius:4px!important}.border-radius-6{border-radius:6px!important}.border-radius-8{border-radius:8px!important}.border-radius-10{border-radius:10px!important}.border-radius-round{border-radius:50px!important}.opacity-01{opacity:.1}.opacity-02{opacity:.2}.opacity-03{opacity:.3}.opacity-04{opacity:.4}.opacity-05{opacity:.5}.opacity-06{opacity:.6}.opacity-07{opacity:.7}.opacity-08{opacity:.8}.opacity-09{opacity:.9}.opacity-10{opacity:1}@media only screen and (max-width:767px){.p-r-100,.p-r-110,.p-r-115,.p-r-120,.p-r-125,.p-r-130,.p-r-135,.p-r-140,.p-r-145,.p-r-150,.p-r-35,.p-r-40,.p-r-45,.p-r-50,.p-r-55,.p-r-60,.p-r-65,.p-r-70,.p-r-75,.p-r-80,.p-r-85,.p-r-90,.p-r-95{padding-right:30px!important}.pull-left-sm{float:left!important}.pull-right-sm{float:right!important}.pull-none-sm{float:none!important}.border.border-hide-sm{border-top:0!important;border-right:0!important;border-bottom:0!important;border-left:0!important}.font-size-100,.font-size-105,.font-size-110,.font-size-115,.font-size-120,.font-size-125,.font-size-130,.font-size-135,.font-size-140,.font-size-145,.font-size-50,.font-size-55,.font-size-60,.font-size-65,.font-size-70,.font-size-75,.font-size-80,.font-size-85,.font-size-90,.font-size-95{font-size:45px!important}.font-size-150,.font-size-155,.font-size-160,.font-size-165,.font-size-170,.font-size-175,.font-size-180,.font-size-185,.font-size-190,.font-size-195,.font-size-200{font-size:130px!important}input.width-10,input.width-15,input.width-20,input.width-25,input.width-30,input.width-35,input.width-40,input.width-45,input.width-50,input.width-55,input.width-60,input.width-65,input.width-70,input.width-75,input.width-80,input.width-85,input.width-90,input.width-95,p.width-10,p.width-15,p.width-20,p.width-25,p.width-30,p.width-35,p.width-40,p.width-45,p.width-50,p.width-55,p.width-60,p.width-65,p.width-70,p.width-75,p.width-80,p.width-85,p.width-90,p.width-95{width:100%!important}.side-nav{left:-200px}}.side-nav{width:200px;background-color:#fff;z-index:1000;top:65px;bottom:0;position:fixed;overflow:hidden;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}@media print{.side-nav{display:none}}.side-nav .side-nav-inner{position:relative;height:100%}.side-nav .side-nav-inner .side-nav-menu{position:relative;list-style:none;margin:0;padding-left:0;padding-top:20px;overflow:auto;border-right:1px solid #e9eaec;height:calc(100vh - 65px)}.side-nav .side-nav-inner .side-nav-menu:after,.side-nav .side-nav-inner .side-nav-menu:before{content:" ";display:table}.side-nav .side-nav-inner .side-nav-menu li{position:relative;display:block}.side-nav .side-nav-inner .side-nav-menu li.dropdown .arrow{position:absolute;right:30px;line-height:30px;transition:all 50ms ease-in;-webkit-transition:all 50ms ease-in;-moz-transition:all 50ms ease-in;-o-transition:all 50ms ease-in;-ms-transition:all 50ms ease-in}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a>.arrow{transform:rotate(90deg);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-o-transform:rotate(90deg);-ms-transform:rotate(90deg)}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>.dropdown-menu{display:block}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>.dropdown-menu .dropdown-menu{padding-left:20px}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>.dropdown-menu .arrow{line-height:25px}.side-nav .side-nav-inner .side-nav-menu li a{color:#8a8a8a;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-o-transition:all .3s ease;-ms-transition:all .3s ease}.side-nav .side-nav-inner .side-nav-menu li a:focus,.side-nav .side-nav-inner .side-nav-menu li a:hover{text-decoration:none;color:#515365}.side-nav .side-nav-inner .side-nav-menu li a:focus .icon-holder,.side-nav .side-nav-inner .side-nav-menu li a:hover .icon-holder{color:#515365}.side-nav .side-nav-inner .side-nav-menu li a.dropdown-toggle:after{display:none;border-radius:0}.side-nav .side-nav-inner .side-nav-menu>li.side-nav-header{text-transform:uppercase;font-size:11px;padding:10px 20px;opacity:.7;margin-top:15px}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu{position:relative;width:100%;box-shadow:none;border:0;border-radius:0;padding-left:50px;padding-top:0;background-color:transparent;float:none}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a{padding:10px 15px}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:focus,.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:hover{background-color:transparent;color:#515365}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li.active a{color:#515365}.side-nav .side-nav-inner .side-nav-menu>li>a{position:relative;display:block;padding:10px 15px;font-weight:500;font-size:15px;white-space:nowrap}.side-nav .side-nav-inner .side-nav-menu>li>a .icon-holder{display:inline-block;height:25px;width:25px;line-height:25px;text-align:center;position:relative;left:0;margin-right:14px;font-size:20px;border-radius:6px;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-o-transition:all .3s ease;-ms-transition:all .3s ease}@media only screen and (min-width:992px){.side-nav-folded .side-nav .side-nav-inner .side-nav-menu>li.side-nav-header,.side-nav-folded .side-nav .side-nav-inner .side-nav-menu>li>a .title{display:none}.side-nav-folded .side-nav{width:70px}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu{overflow-x:hidden}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu>li>a{padding-left:20px}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu li.dropdown .arrow{opacity:0}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu li.dropdown.open ul.dropdown-menu{display:none!important}.side-nav-folded .side-nav:hover{width:200px;background:#fff;z-index:9999}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu>li.side-nav-header{display:block}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu>li>a .title{display:inline-block}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu li.dropdown .arrow{opacity:1}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu li.open>ul.dropdown-menu{display:block!important}}@media only screen and (max-width:992px){.side-nav .side-nav-inner .side-nav-menu li.dropdown .arrow{right:25px}.side-nav-folded .side-nav{left:-200px}}.side-nav-folded .header .header-container .nav-logo{width:70px;padding:0}@media only screen and (max-width:767px){.side-nav-folded .header .header-container .nav-logo{width:0;overflow:hidden}.side-nav-expand{overflow:hidden}}.side-nav-folded .header .header-container .nav-logo>a .logo{width:70px;background-position:center center}.side-nav-folded .header .nav-left>li>a.sidenav-fold-toggler i:before{content:"\F054"}@media only screen and (max-width:767px){.side-nav-expand .side-nav{left:0}.side-nav-expand .header .header-container .nav-logo{width:0}.side-nav-expand .header .header-container .nav-left>li>a.sidenav-expand-toggler i:before{content:"\F04D"}.side-nav-backdrop{position:fixed;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background:#515365;background:rgba(81,83,101,.5)}}.header{display:block;height:65px;width:100%;position:fixed;padding:0;z-index:1040;background-color:#fff;border-bottom:1px solid #e9eaec;margin-bottom:0;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}@media print{.header{display:none}}@media only screen and (max-width:992px){.header{width:100%}}.header .header-container:after,.header .header-container:before{content:" ";display:table}.header .header-container .nav-logo{padding:0 20px;line-height:0;float:left;width:200px;transition:all .2s ease;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}.header .header-container .nav-logo>a{display:inline-block;max-width:200px;width:100%}.header .header-container .nav-logo>a .logo{background-repeat:no-repeat;background-position:center left;display:inline-block;width:100%;min-height:calc(65px - 1px)}.header .header-container .nav-logo>a .logo.logo-white{display:none}@media only screen and (max-width:992px){.header .header-container .nav-logo{width:0;padding:0}}.header .header-container .nav-left,.header .header-container .nav-right{position:relative;list-style:none;padding-left:0;margin-bottom:0}.header .header-container .nav-left>li,.header .header-container .nav-right>li{float:left}.header .header-container .nav-left>li>a,.header .header-container .nav-right>li>a{padding:0 12px;line-height:calc(65px - 3px);min-height:calc(65px - 3px);color:#8a8a8a;display:block;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.header .header-container .nav-left>li>a i,.header .header-container .nav-right>li>a i{font-size:22px}.header .header-container .nav-left>li>a:focus,.header .header-container .nav-left>li>a:hover,.header .header-container .nav-right>li>a:focus,.header .header-container .nav-right>li>a:hover{text-decoration:none;color:#515365}.header .header-container .nav-left>li>a.dropdown-toggle:after,.header .header-container .nav-right>li>a.dropdown-toggle:after{display:none;border-radius:0}@media only screen and (min-width:767px){.header .header-container .nav-left>li>a.sidenav-fold-toggler,.header .header-container .nav-right>li>a.sidenav-fold-toggler{display:block}.header .header-container .nav-left>li>a.sidenav-expand-toggler,.header .header-container .nav-right>li>a.sidenav-expand-toggler{display:none}}.header .header-container .nav-left .user-profile .profile-img,.header .header-container .nav-right .user-profile .profile-img{width:35px;border-radius:50%;margin-top:12px;float:left}@media only screen and (max-width:992px){.header .header-container .nav-left>li>a,.header .header-container .nav-right>li>a{padding:0 10px}.header .header-container .nav-left .user-profile,.header .header-container .nav-right .user-profile{border-right:0;border-left:0}.header .header-container .nav-left .user-profile .profile-img,.header .header-container .nav-right .user-profile .profile-img{width:30px;margin-right:0}}.header .header-container .nav-left .notifications,.header .header-container .nav-right .notifications{position:relative}.header .header-container .nav-left .notifications .counter,.header .header-container .nav-right .notifications .counter{position:absolute;right:6px;top:12px;background-color:#fd3259;color:#fff;padding:3px 5.5px;border-radius:50px;line-height:1;font-size:10px}.header .header-container .nav-left{float:left}.content-footer .footer .go-right,.header .header-container .nav-right{float:right}@media only screen and (max-width:767px){.header .header-container .nav-left>li>a.sidenav-fold-toggler,.header .header-container .nav-right>li>a.sidenav-fold-toggler{display:none}.header .header-container .nav-left>li>a.sidenav-expand-toggler,.header .header-container .nav-right>li>a.sidenav-expand-toggler{display:block}.header .header-container .nav-right .dropdown.dropdown-animated.scale-left .dropdown-menu{right:-40px!important}.header .header-container .search-input input{width:85px}}.header .header-container .search-box .search-icon-close,.header .header-container .search-box.active .search-icon{display:none}.header .header-container .search-box.active .search-icon-close{display:inline-block}.header .header-container .search-input{display:none}.header .header-container .search-input.active{display:inline-block}.header .header-container .search-input input{border:0;box-shadow:none;background-color:transparent;outline:0;height:40px;margin-top:10px;padding:5px;font-size:16px}.header .header-container .search-input input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input .search-predict{display:none;position:absolute;top:65px;width:350px;min-height:50px;max-height:500px;background-color:#fff;color:#8a8a8a;border-radius:4px;-webkit-box-shadow:0 0 8px 0 rgba(0,0,0,.2);-moz-box-shadow:0 0 8px 0 rgba(0,0,0,.2);box-shadow:0 0 8px 0 rgba(0,0,0,.2)}.header .header-container .search-input .search-predict.active{display:block}.header .header-container .search-input .search-predict .search-wrapper{position:relative;max-height:400px;overflow-y:auto}.header .header-container .search-input .search-footer{border-top:1px solid #e9eaec;text-align:center;padding:15px;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.content-footer{padding:0 30px}.content-footer .footer{padding:20px 0;font-size:90%;border-top:1px solid #e9eaec}@media only screen and (max-width:767px){.header .header-container .search-input .search-predict{left:40px}.content-footer .footer{text-align:center}.content-footer .footer .go-right{float:none;margin-top:15px;display:block}}.page-container{min-height:100vh;padding-left:200px;transition:all .2s ease;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}@media print{.page-container{padding-left:0}}@media only screen and (max-width:992px){.page-container{padding-left:0}}.page-container .main-content{padding:calc(65px + 35px) 15px 15px;min-height:calc(100vh - 65px)}.page-container .main-content.full-container{padding:95px 0 0}@media print{.page-container .main-content{padding:10px 0}}@media only screen and (max-width:992px){.page-container .main-content{padding:85px 10px 10px}}.page-container .page-header{margin-bottom:30px}.page-container .page-header .header-title{display:inline-block;font-size:23px;margin-bottom:0;padding-bottom:5px;border-right:1px solid #e9eaec;padding-right:20px;line-height:1}@media only screen and (max-width:767px){.page-container .page-header .header-title{border-right:0;display:block;margin-bottom:15px}}.page-container .page-header .header-sub-title{display:inline-block;padding-left:20px}@media only screen and (max-width:767px){.page-container .page-header .header-sub-title{padding-left:0;display:block}}@media only screen and (min-width:992px){.side-nav-folded .page-container{padding-left:70px}}@media only screen and (max-width:992px){.side-nav-folded .page-container{padding-left:0}}.widget-credit-card{max-width:430px}.side-nav-dark .side-nav{background-color:#223143;color:#99abb4}.side-nav-dark .side-nav .side-nav-logo{border-bottom:1px solid rgba(120,130,140,.3);border-right:1px solid transparent}.side-nav-dark .side-nav .side-nav-logo a .logo.logo-white{display:block}.side-nav-dark .side-nav .side-nav-logo a .logo.logo-dark{display:none}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu{border-right:1px solid transparent}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a{color:#99abb4;font-weight:400}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:focus .arrow,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:focus .icon-holder,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:focus .title,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:hover .arrow,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:hover .icon-holder,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:hover .title,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .arrow,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .title,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li.active>a,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:focus,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:hover{color:#fff}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu{background:#192532;background:rgba(25,37,50,.5)}.header-primary .header{background-color:#6569df}.header-primary .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-primary .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-primary .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#6569df}.header-info .header{background-color:#04a1f4}.header-info .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-info .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-info .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#04a1f4}.header-success .header{background-color:#2acfd2}.header-success .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-success .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-success .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#24d5d8}.header-warning .header{background-color:#fecd2f}.header-warning .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-warning .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-warning .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#fecd2f}.header-danger .header{background-color:#fd3259}.header-danger .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-danger .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-danger .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#fd3259}.header-dark .header{background-color:#334a65}.theme-configurator{position:relative}.color-selector label,.theme-selector label{position:relative;display:inline-block;width:25px;height:25px;margin-right:5px;margin-bottom:5px;border-radius:50%;cursor:pointer}.color-selector input,.theme-selector input{opacity:0}.color-selector input:checked~.theme-color:after,.theme-selector input:checked~.theme-color:after{content:"\e64c";font-family:themify;font-size:12px;font-weight:700;display:block;color:#fff;width:100%;text-align:center;position:absolute;top:50%;transform:translateY(-50%);-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%)}.color-selector input:checked~.theme-color.bg-white:after,.theme-selector input:checked~.theme-color.bg-white:after{color:#515365}.color-selector .theme-color,.theme-selector .theme-color{position:absolute;top:0;left:0;right:0;bottom:0;border-radius:50%}.color-pallet{border:1px solid #e9eaec;min-width:180px;margin-bottom:20px}.color-pallet .box{height:120px}.color-pallet .desc{padding:10px}.alert{padding:15px 20px;border-radius:0}.alert-default{color:#7d7d7d;background-color:#f1f2f3;border-color:#d9dade}.alert-default p{color:#7d7d7d}.alert-default hr{border-color:#e9eaec}.alert-primary,.alert-primary hr{border-color:#cfd0f5}.alert-primary{color:#6569df;background-color:#f0f1fc}.alert-primary p{color:#6569df}.alert-success,.alert-success hr{border-color:#8febec}.alert-success{color:#24d5d8;background-color:#e7fbfb}.alert-success p{color:#24d5d8}.alert-info,.alert-info p{color:#04a1f4}.alert-info,.alert-info hr{border-color:#94d9fd}.alert-info{background-color:#e9f7ff}.alert-warning,.alert-warning hr{border-color:#fedf7b}.alert-warning{color:#fecd2f;background-color:#fffefa}.alert-warning p{color:#fecd2f}.alert-danger,.alert-danger p{color:#fd3259}.alert-danger,.alert-danger hr{border-color:#fecad4}.alert-danger{background-color:#fff7f9}.alert-danger-gradient,.alert-info-gradient,.alert-primary-gradient,.alert-success-gradient,.alert-warning-gradient{color:#fff;border-radius:4px}.alert-primary-gradient{border-color:transparent;background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.alert-success-gradient{border-color:transparent;background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.alert-info-gradient{border-color:transparent;background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.alert-warning-gradient{border-color:transparent;background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.alert-danger-gradient{border-color:transparent;background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.alert-float{border-color:transparent;-webkit-box-shadow:0 7px 20px 2px rgba(9,4,25,.1);-moz-box-shadow:0 7px 20px 2px rgba(9,4,25,.1);box-shadow:0 7px 20px 2px rgba(9,4,25,.1)}.alert-icon{font-size:30px;padding:0 7px}button{outline:0;box-shadow:none}button:focus{outline:0}button.active:focus,button:active:focus{outline:0;box-shadow:none}button.disabled,button:disabled{opacity:.5;cursor:not-allowed}.btn-danger.disabled,.btn-danger:disabled,.btn-info.disabled,.btn-info:disabled,.btn-primary.disabled,.btn-primary:disabled,.btn-success.disabled,.btn-success:disabled,.btn-warning.disabled,.btn-warning:disabled{opacity:.35}.btn{cursor:pointer;font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;font-size:14px;padding:7px 20px;margin-right:5px;margin-bottom:10px;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.modal.modal-fs,.modal.modal-left,.modal.modal-right{padding-right:0!important}.btn.dropdown-toggle,.modal-footer .btn,.modal-header h1,.modal-header h2,.modal-header h3,.modal-header h4,.modal-header h5,.modal-header h6{margin-bottom:0}.btn:focus{outline:0;box-shadow:none}.btn.active:focus,.btn:active:focus{outline:0}.btn-default{color:#515365;background-color:transparent;border-color:#dbdde0}.btn-default.active:focus,.btn-default.active:hover,.btn-default:active,.btn-default:active:focus,.btn-default:active:hover,.btn-default:focus,.btn-default:hover{color:#515365;background-color:#eeeff1;border-color:#eeeff1}.btn-primary{background-color:#6569df;border-color:#6569df;color:#fff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#7a7ee3;border-color:#7a7ee3}.btn-primary.active,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active{background-color:#5054db;border-color:#5054db}.btn-primary.disabled,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary:disabled,.btn-primary:disabled:focus,.btn-primary:disabled:hover,.btn-primary:not([disabled]):not(.disabled).active,.btn-primary:not([disabled]):not(.disabled):active{background-color:#6569df;border-color:#6569df}.btn-primary:not([disabled]):not(.disabled).active:focus,.btn-primary:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-primary.btn-outline{background-color:transparent;color:#6569df;border-color:#6569df}.btn-primary.btn-outline:focus,.btn-primary.btn-outline:hover{background-color:#6569df;color:#fff}.btn-success{background-color:#24d5d8;border-color:#24d5d8;color:#fff}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#38dbde;border-color:#38dbde}.btn-success.active,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active{background-color:#20bfc2;border-color:#20bfc2}.btn-success.disabled,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success:disabled,.btn-success:disabled:focus,.btn-success:disabled:hover,.btn-success:not([disabled]):not(.disabled).active,.btn-success:not([disabled]):not(.disabled):active{background-color:#24d5d8;border-color:#24d5d8}.btn-success:not([disabled]):not(.disabled).active:focus,.btn-success:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-success.btn-outline{background-color:transparent;color:#24d5d8;border-color:#24d5d8}.btn-success.btn-outline:focus,.btn-success.btn-outline:hover{background-color:#24d5d8;color:#fff}.btn-info{background-color:#04a1f4;border-color:#04a1f4;color:#fff}.btn-info:focus,.btn-info:hover{color:#fff;background-color:#16acfb;border-color:#16acfb}.btn-info.active,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active{background-color:#0490db;border-color:#0490db}.btn-info.disabled,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info:disabled,.btn-info:disabled:focus,.btn-info:disabled:hover,.btn-info:not([disabled]):not(.disabled).active,.btn-info:not([disabled]):not(.disabled):active{background-color:#04a1f4;border-color:#04a1f4}.btn-info:not([disabled]):not(.disabled).active:focus,.btn-info:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-info.btn-outline{background-color:transparent;color:#04a1f4;border-color:#04a1f4}.btn-info.btn-outline:focus,.btn-info.btn-outline:hover{background-color:#04a1f4;color:#fff}.btn-warning{background-color:#fecd2f;border-color:#fecd2f;color:#fff}.btn-warning:focus,.btn-warning:hover{color:#fff;background-color:#fed348;border-color:#fed348}.btn-warning.active,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active{background-color:#fec716;border-color:#fec716}.btn-warning.disabled,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning:disabled,.btn-warning:disabled:focus,.btn-warning:disabled:hover,.btn-warning:not([disabled]):not(.disabled).active,.btn-warning:not([disabled]):not(.disabled):active{background-color:#fecd2f;border-color:#fecd2f}.btn-warning:not([disabled]):not(.disabled).active:focus,.btn-warning:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-warning.btn-outline{background-color:transparent;color:#fecd2f;border-color:#fecd2f}.btn-warning.btn-outline:focus,.btn-warning.btn-outline:hover{background-color:#fecd2f;color:#fff}.btn-danger{background-color:#fd3259;border-color:#fd3259;color:#fff}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#fd4b6d;border-color:#fd4b6d}.btn-danger.active,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active{background-color:#fd1945;border-color:#fd1945}.btn-danger.disabled,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger:disabled,.btn-danger:disabled:focus,.btn-danger:disabled:hover,.btn-danger:not([disabled]):not(.disabled).active,.btn-danger:not([disabled]):not(.disabled):active{background-color:#fd3259;border-color:#fd3259}.btn-danger:not([disabled]):not(.disabled).active:focus,.btn-danger:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-danger.btn-outline{background-color:transparent;color:#fd3259;border-color:#fd3259}.btn-gradient-danger,.btn-gradient-info,.btn-gradient-primary,.btn-gradient-success,.btn-gradient-warning{border:0;color:#fff}.btn-danger.btn-outline:focus,.btn-danger.btn-outline:hover{background-color:#fd3259;color:#fff}.btn-gradient-primary,.btn-gradient-primary.active,.btn-gradient-primary:active,.btn-gradient-primary:focus,.btn-gradient-primary:hover,.btn-gradient-primary:not([disabled]):not(.disabled).active,.btn-gradient-primary:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.btn-gradient-primary:focus,.btn-gradient-primary:hover{opacity:.7;color:#fff}.btn-gradient-primary.active,.btn-gradient-primary:active{color:#fff}.btn-gradient-primary.disabled:focus,.btn-gradient-primary.disabled:hover{opacity:.5}.btn-gradient-success,.btn-gradient-success.active,.btn-gradient-success:active,.btn-gradient-success:focus,.btn-gradient-success:hover,.btn-gradient-success:not([disabled]):not(.disabled).active,.btn-gradient-success:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.btn-gradient-success:focus,.btn-gradient-success:hover{opacity:.7;color:#fff}.btn-gradient-success.active,.btn-gradient-success:active{color:#fff}.btn-gradient-success.disabled:focus,.btn-gradient-success.disabled:hover{opacity:.5}.btn-gradient-info,.btn-gradient-info.active,.btn-gradient-info:active,.btn-gradient-info:focus,.btn-gradient-info:hover,.btn-gradient-info:not([disabled]):not(.disabled).active,.btn-gradient-info:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.btn-gradient-info:focus,.btn-gradient-info:hover{opacity:.7;color:#fff}.btn-gradient-info.active,.btn-gradient-info:active{color:#fff}.btn-gradient-info.disabled:focus,.btn-gradient-info.disabled:hover{opacity:.5}.btn-gradient-warning,.btn-gradient-warning.active,.btn-gradient-warning:active,.btn-gradient-warning:focus,.btn-gradient-warning:hover,.btn-gradient-warning:not([disabled]):not(.disabled).active,.btn-gradient-warning:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.btn-gradient-warning:focus,.btn-gradient-warning:hover{opacity:.7;color:#fff}.btn-gradient-warning.active,.btn-gradient-warning:active{color:#fff}.btn-gradient-warning.disabled:focus,.btn-gradient-warning.disabled:hover{opacity:.5}.btn-gradient-danger,.btn-gradient-danger.active,.btn-gradient-danger:active,.btn-gradient-danger:focus,.btn-gradient-danger:hover,.btn-gradient-danger:not([disabled]):not(.disabled).active,.btn-gradient-danger:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.btn-gradient-danger:focus,.btn-gradient-danger:hover{opacity:.7;color:#fff}.btn-gradient-danger.disabled:focus,.btn-gradient-danger.disabled:hover,.checkbox input[type=checkbox].disabled+label,.checkbox input[type=checkbox]:disabled+label,.radio input[type=radio].disabled+label,.radio input[type=radio]:disabled+label{opacity:.5}.btn-gradient-danger.active,.btn-gradient-danger:active{color:#fff}.show>.dropdown-toggle.btn-primary{background-color:#5054db;border-color:#5054db}.show>.dropdown-toggle.btn-primary:focus,.show>.dropdown-toggle.btn-primary:hover{background-color:#5054db;border-color:#5054db;box-shadow:none}.show>.dropdown-toggle.btn-success{background-color:#20bfc2;border-color:#20bfc2}.show>.dropdown-toggle.btn-success:focus,.show>.dropdown-toggle.btn-success:hover{background-color:#20bfc2;border-color:#20bfc2;box-shadow:none}.show>.dropdown-toggle.btn-info{background-color:#0490db;border-color:#0490db}.show>.dropdown-toggle.btn-info:focus,.show>.dropdown-toggle.btn-info:hover{background-color:#0490db;border-color:#0490db;box-shadow:none}.show>.dropdown-toggle.btn-warning{background-color:#fec716;border-color:#fec716}.show>.dropdown-toggle.btn-warning:focus,.show>.dropdown-toggle.btn-warning:hover{background-color:#fec716;border-color:#fec716;box-shadow:none}.show>.dropdown-toggle.btn-danger{background-color:#fd1945;border-color:#fd1945}.show>.dropdown-toggle.btn-danger:focus,.show>.dropdown-toggle.btn-danger:hover{background-color:#fd1945;border-color:#fd1945;box-shadow:none}.modal .modal-dialog{transition:all .2s ease-out;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;-ms-transition:all .2s ease-out}.modal:not(.modal-fs) .modal-dialog,.modal:not(.modal-left) .modal-dialog,.modal:not(.modal-right) .modal-dialog{transform:translateY(20px);-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-o-transform:translateY(20px);-ms-transform:translateY(20px)}.modal:not(.modal-fs).show .modal-dialog,.modal:not(.modal-left).show .modal-dialog,.modal:not(.modal-right).show .modal-dialog{transform:translateY(0);-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0)}.modal.modal-right .modal-dialog{transform:translateX(100%);-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-o-transform:translateX(100%);-ms-transform:translateX(100%)}.modal.modal-right.show .modal-dialog{transform:translateX(0);-webkit-transform:translateX(0);-moz-transform:translateX(0);-o-transform:translateX(0);-ms-transform:translateX(0)}.modal.modal-left .modal-dialog{transform:translateX(-100%);-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-o-transform:translateX(-100%);-ms-transform:translateX(-100%)}.modal.modal-left.show .modal-dialog{transform:translateX(0);-webkit-transform:translateX(0);-moz-transform:translateX(0);-o-transform:translateX(0);-ms-transform:translateX(0)}.modal.modal-fs .modal-dialog{transform:scale(.7);-webkit-transform:scale(.7);-moz-transform:scale(.7);-o-transform:scale(.7);-ms-transform:scale(.7)}.modal.modal-fs.show .modal-dialog{transform:scale(1);-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1)}.modal-header{padding:15px 20px 5px;border-bottom:0}.modal-body,.modal-footer{padding:15px 20px}.modal-footer{border-top:1px solid #e9eaec;text-align:left}.modal-footer .btn+.btn{margin-left:0}.modal-content{position:relative;background-color:#fff;border:0;border-radius:0;outline:0;-webkit-box-shadow:0 16px 24px rgba(43,47,49,.25);-moz-box-shadow:0 16px 24px rgba(43,47,49,.25);box-shadow:0 16px 24px rgba(43,47,49,.25)}.modal-left .modal-dialog,.modal-right .modal-dialog{width:400px;height:100%;margin:0 auto 0 0}@media only screen and (max-width:767px){.modal-left .modal-dialog,.modal-right .modal-dialog{width:calc(100% - 50px)}}.modal-left .modal-dialog .modal-content,.modal-right .modal-dialog .modal-content{height:100%;border-radius:0}.modal-left .modal-dialog .modal-content .side-modal-wrapper,.modal-right .modal-dialog .modal-content .side-modal-wrapper{height:100%;position:relative}.modal-left .modal-dialog .modal-content .modal-footer,.modal-right .modal-dialog .modal-content .modal-footer{position:absolute;bottom:0;width:100%}.modal-right .modal-dialog{margin:0 0 0 auto}.modal-backdrop{z-index:1040;background-color:#515365}.modal-fs .modal-dialog{width:100%;margin:0 auto;height:100%;max-width:none}.list-link,.list-media{margin-bottom:0}.modal-fs .modal-dialog .modal-content{height:100%;border-radius:0;background:#fff;background:rgba(255,255,255,.95)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{background-color:#fafafa;border:1px solid #e9eaec}.modal-fs .modal-close{position:absolute;top:20px;right:20px;padding:7px 10px;border:1px solid #9ea0b1;border-radius:50px;color:#9ea0b1}.list,.list li{position:relative}.modal-fs .modal-close:focus,.modal-fs .modal-close:hover{color:#515365;text-decoration:none;border:1px solid #515365}.list li{padding-bottom:10px}.list.arrow,.list.bullet,.list.dash,.list.star,.list.tick{list-style:none;padding-left:0}.list.arrow>li,.list.bullet>li,.list.dash>li,.list.star>li,.list.tick>li{padding-left:30px}.list.arrow>li:before,.list.bullet>li:before,.list.dash>li:before,.list.star>li:before,.list.tick>li:before{font-family:themify;position:absolute;left:0}.list.tick>li:before{content:"\e64c"}.list.star>li:before{content:"\e60a"}.list.dash>li:before{content:"-"}.list.bullet>li:before{content:"\e724"}.list.arrow>li:before{content:"\e649";font-size:10px;top:4px}.bg-overlay:before,.card-refresh:after,.card-refresh:before,.list-media .media-img .status:before{content:""}.list.decimal{list-style-type:decimal;padding-left:20px}.list.decimal li{padding-left:10px}.list.upper-roman{list-style-type:upper-roman;padding-left:20px}.list.upper-roman li{padding-left:10px}.list.lower-alpha{list-style-type:lower-alpha;padding-left:20px}.list.lower-alpha li{padding-left:10px}.list.bullet-primary>li:before{color:#6569df}.list.bullet-info li:before{color:#04a1f4}.list.bullet-success li:before{color:#24d5d8}.list.bullet-warning li:before{color:#fecd2f}.list.bullet-danger li:before{color:#fd3259}.list.bullet-white li:before{color:#fff}.list.bullet-dark li:before{color:#515365}.list-group-item{border:1px solid #e9eaec}.list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.list-group-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.list-group-item.active{color:#515365}.list-group-item.disabled{color:#9ea0b1}.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#9ea0b1;background-color:transparent;border:1px solid #e9eaec}.list-group-item-action{color:#515365}.list-group-item-action:focus,.list-group-item-action:hover{color:#515365;background-color:#fafafa}.list-media{display:block;position:relative;padding-left:0;list-style:none}.list-media>.list-item{display:block}.list-media>.list-item>a{display:block;position:relative;padding:12px 0}.list-media>.list-item>a:focus,.list-media>.list-item>a:hover{text-decoration:none}.list-media>.list-item.active{background-color:#fafafa}.list-media>.list-item .media-hover:focus,.list-media>.list-item .media-hover:hover{text-decoration:none;background-color:#fafafa}.list-media .media-img{position:relative;float:left}.list-media .media-img .icon-avatar,.list-media .media-img img{line-height:40px;height:40px;width:40px;text-align:center;font-size:17px;border-radius:50px;color:#fff}.list-media .media-img .status{right:0;bottom:0;position:absolute;left:auto;top:auto}.list-media .media-img .status:before{position:absolute;background-color:transparent;width:15px;height:14px;bottom:-5px;right:-6px;border-radius:50px;border:2px solid #fff}.list-media .info{padding-left:55px;min-height:40px;height:auto;position:relative}.list-media .info .title{display:block;color:#515365;line-height:1.5}.list-media .info .title.pdd-top-5{padding-top:7px!important}.list-media .info .sub-title{display:block;font-size:12.5px;color:#adadad;color:rgba(138,138,138,.7);max-width:90%}.list-media .info .float-item{position:absolute;right:0;color:#8a8a8a;top:50%;font-size:12px;transform:translateY(-50%);-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%)}.list-media .info.status{padding-left:0;min-height:auto;height:10px;position:absolute}.list-inline>li{display:inline-block;margin-right:10px}.list-media-horizon{display:inline-block;margin-bottom:0}.list-media-horizon>li{float:left;margin-right:0}.list-media-horizon>li>a img,.list-media-horizon>li>img{width:35px;height:35px;border-radius:100%;overflow:hidden;border:2px solid #fff;display:block}.list-media-horizon>li.all-members{border-radius:100%}.list-media-horizon>li.all-members>a{width:35px;line-height:35px;display:block;text-align:center;border-radius:100%;background-color:#fafafa;color:#8a8a8a}.list-media-horizon>li.add-member>a{border:2px dashed #e9eaec;width:35px;line-height:30px;display:block;text-align:center;border-radius:100%;color:#ced0d4;margin-left:5px}.card-toolbar ul>li,.list-label>li,.status{display:inline-block}.list-link li{padding:10px 0}.list-link li a{color:#8a8a8a}.list-link li a:focus,.list-link li a:hover{color:#515365;text-decoration:none}.list-label{padding-left:0;line-height:0}.list-label>li{height:2px;width:40px;background:#fafafa;border-radius:50px;margin-right:5px}.badge{padding:5px 7px;font-size:80%;font-weight:500;line-height:1}.badge-default{color:#515365;background-color:transparent;border:1px solid #dbdde0}.badge-default[href]:focus,.badge-default[href]:hover{background-color:#f7f7f7;color:#515365}.badge-primary{background-color:#6569df}.badge-primary[href]:focus,.badge-primary[href]:hover{background-color:#7a7ee3}.badge-success{background-color:#24d5d8}.badge-success[href]:focus,.badge-success[href]:hover{background-color:#38dbde}.badge-info{background-color:#04a1f4}.badge-info[href]:focus,.badge-info[href]:hover{background-color:#16acfb}.badge-warning{color:#fff;background-color:#fecd2f}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#fff;background-color:#fed348}.badge-danger{background-color:#fd3259}.badge-danger[href]:focus,.badge-danger[href]:hover{background-color:#fd4b6d}.badge-gradient-primary{color:#fff;background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.badge-gradient-success{color:#fff;background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.badge-gradient-info{color:#fff;background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.badge-gradient-warning{color:#fff;background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.badge-gradient-danger{color:#fff;background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.badge-xl{padding:9px 15px;font-size:100%}.badge-lg{padding:8px 13px;font-size:90%}.badge-sm{padding:3px 5px;font-size:75%}.status{width:10px;height:10px;background-color:#fff;border-radius:50px;border:3px solid #c0c3c9}.status.primary{border-color:#6569df}.status.info{border-color:#04a1f4}.status.online,.status.success{border-color:#24d5d8}.status.busy,.status.danger{border-color:#fd3259}.status.away,.status.warning{border-color:#fecd2f}.status.gradient{border:0;background:#fafafa}.status.gradient.primary{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.status.gradient.info{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.status.gradient.online,.status.gradient.success{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.status.gradient.away,.status.gradient.warning{background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.status.gradient.busy,.status.gradient.danger{background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.card{position:relative;background-color:#fff;margin-bottom:30px;border:1px solid #e9eaec;border-radius:0;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.card-footer,.card-header{position:relative;min-height:55px;background-color:transparent}.card-header:first-child,.popover{border-radius:0}.card .bg-danger,.card .bg-gradient-danger,.card .bg-gradient-info,.card .bg-gradient-primary,.card .bg-gradient-success,.card .bg-gradient-warning,.card .bg-info,.card .bg-primary,.card .bg-success,.card .bg-warning,.card.bg-danger,.card.bg-gradient-danger,.card.bg-gradient-info,.card.bg-gradient-primary,.card.bg-gradient-success,.card.bg-gradient-warning,.card.bg-info,.card.bg-primary,.card.bg-success,.card.bg-warning{color:#f7f7f7}.card .bg-danger h1,.card .bg-danger h2,.card .bg-danger h3,.card .bg-danger h4,.card .bg-danger h5,.card .bg-danger h6,.card .bg-gradient-danger h1,.card .bg-gradient-danger h2,.card .bg-gradient-danger h3,.card .bg-gradient-danger h4,.card .bg-gradient-danger h5,.card .bg-gradient-danger h6,.card .bg-gradient-info h1,.card .bg-gradient-info h2,.card .bg-gradient-info h3,.card .bg-gradient-info h4,.card .bg-gradient-info h5,.card .bg-gradient-info h6,.card .bg-gradient-primary h1,.card .bg-gradient-primary h2,.card .bg-gradient-primary h3,.card .bg-gradient-primary h4,.card .bg-gradient-primary h5,.card .bg-gradient-primary h6,.card .bg-gradient-success h1,.card .bg-gradient-success h2,.card .bg-gradient-success h3,.card .bg-gradient-success h4,.card .bg-gradient-success h5,.card .bg-gradient-success h6,.card .bg-gradient-warning h1,.card .bg-gradient-warning h2,.card .bg-gradient-warning h3,.card .bg-gradient-warning h4,.card .bg-gradient-warning h5,.card .bg-gradient-warning h6,.card .bg-info h1,.card .bg-info h2,.card .bg-info h3,.card .bg-info h4,.card .bg-info h5,.card .bg-info h6,.card .bg-primary h1,.card .bg-primary h2,.card .bg-primary h3,.card .bg-primary h4,.card .bg-primary h5,.card .bg-primary h6,.card .bg-success h1,.card .bg-success h2,.card .bg-success h3,.card .bg-success h4,.card .bg-success h5,.card .bg-success h6,.card .bg-warning h1,.card .bg-warning h2,.card .bg-warning h3,.card .bg-warning h4,.card .bg-warning h5,.card .bg-warning h6,.card.bg-danger h1,.card.bg-danger h2,.card.bg-danger h3,.card.bg-danger h4,.card.bg-danger h5,.card.bg-danger h6,.card.bg-gradient-danger h1,.card.bg-gradient-danger h2,.card.bg-gradient-danger h3,.card.bg-gradient-danger h4,.card.bg-gradient-danger h5,.card.bg-gradient-danger h6,.card.bg-gradient-info h1,.card.bg-gradient-info h2,.card.bg-gradient-info h3,.card.bg-gradient-info h4,.card.bg-gradient-info h5,.card.bg-gradient-info h6,.card.bg-gradient-primary h1,.card.bg-gradient-primary h2,.card.bg-gradient-primary h3,.card.bg-gradient-primary h4,.card.bg-gradient-primary h5,.card.bg-gradient-primary h6,.card.bg-gradient-success h1,.card.bg-gradient-success h2,.card.bg-gradient-success h3,.card.bg-gradient-success h4,.card.bg-gradient-success h5,.card.bg-gradient-success h6,.card.bg-gradient-warning h1,.card.bg-gradient-warning h2,.card.bg-gradient-warning h3,.card.bg-gradient-warning h4,.card.bg-gradient-warning h5,.card.bg-gradient-warning h6,.card.bg-info h1,.card.bg-info h2,.card.bg-info h3,.card.bg-info h4,.card.bg-info h5,.card.bg-info h6,.card.bg-primary h1,.card.bg-primary h2,.card.bg-primary h3,.card.bg-primary h4,.card.bg-primary h5,.card.bg-primary h6,.card.bg-success h1,.card.bg-success h2,.card.bg-success h3,.card.bg-success h4,.card.bg-success h5,.card.bg-success h6,.card.bg-warning h1,.card.bg-warning h2,.card.bg-warning h3,.card.bg-warning h4,.card.bg-warning h5,.card.bg-warning h6{color:#fff}.card .bg-danger p,.card .bg-gradient-danger p,.card .bg-gradient-info p,.card .bg-gradient-primary p,.card .bg-gradient-success p,.card .bg-gradient-warning p,.card .bg-info p,.card .bg-primary p,.card .bg-success p,.card .bg-warning p,.card.bg-danger p,.card.bg-gradient-danger p,.card.bg-gradient-info p,.card.bg-gradient-primary p,.card.bg-gradient-success p,.card.bg-gradient-warning p,.card.bg-info p,.card.bg-primary p,.card.bg-success p,.card.bg-warning p{color:#f7f7f7}.card .bg-danger .card-header,.card .bg-gradient-danger .card-header,.card .bg-gradient-info .card-header,.card .bg-gradient-primary .card-header,.card .bg-gradient-success .card-header,.card .bg-gradient-warning .card-header,.card .bg-info .card-header,.card .bg-primary .card-header,.card .bg-success .card-header,.card .bg-warning .card-header,.card.bg-danger .card-header,.card.bg-gradient-danger .card-header,.card.bg-gradient-info .card-header,.card.bg-gradient-primary .card-header,.card.bg-gradient-success .card-header,.card.bg-gradient-warning .card-header,.card.bg-info .card-header,.card.bg-primary .card-header,.card.bg-success .card-header,.card.bg-warning .card-header{border-color:rgba(255,255,255,.3)!important}.card .bg-danger .card-footer,.card .bg-gradient-danger .card-footer,.card .bg-gradient-info .card-footer,.card .bg-gradient-primary .card-footer,.card .bg-gradient-success .card-footer,.card .bg-gradient-warning .card-footer,.card .bg-info .card-footer,.card .bg-primary .card-footer,.card .bg-success .card-footer,.card .bg-warning .card-footer,.card.bg-danger .card-footer,.card.bg-gradient-danger .card-footer,.card.bg-gradient-info .card-footer,.card.bg-gradient-primary .card-footer,.card.bg-gradient-success .card-footer,.card.bg-gradient-warning .card-footer,.card.bg-info .card-footer,.card.bg-primary .card-footer,.card.bg-success .card-footer,.card.bg-warning .card-footer{border-top:1px solid rgba(255,255,255,.2)}.card.card-shadow{-webkit-box-shadow:0 7px 20px 2px rgba(0,0,0,.2);-moz-box-shadow:0 7px 20px 2px rgba(0,0,0,.2);box-shadow:0 7px 20px 2px rgba(0,0,0,.2)}.card-header{padding:15px 25px;border-bottom:0}.card-header .card-title{margin-bottom:0;display:inline-block}.card-header p{padding-top:8px;margin-bottom:0}.card-body{padding:25px;position:relative}.card-footer{padding:10px 15px;border-top:1px solid #e9eaec}.card-footer .btn{margin-bottom:0}.card-toolbar{float:right}.card-toolbar ul{list-style:none;padding-left:0}.card-toolbar ul>li>.btn,.card-toolbar ul>li>a{margin-bottom:0;margin-right:10px;display:block}.card-toolbar ul>li>.btn{padding:7px 15px;font-size:13px}.bg-overlay>.card-toolbar{position:absolute;right:15px;top:10px}.card-title{color:#515365;margin-top:0;margin-bottom:15px}.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-refresh:before{position:absolute;top:0;left:0;width:100%;height:100%;z-index:4;background:#fff;background:rgba(255,255,255,.7)}.card-refresh:after{position:absolute;top:calc(50% - 20px);left:calc(50% - 20px);border:3px solid #e9eaec;border-top:3px solid #24d5d8;border-radius:50%;width:40px;height:40px;z-index:5;-webkit-animation:spin 1.2s linear infinite;-moz-animation:spin 1.2s linear infinite;-ms-animation:spin 1.2s linear infinite;-o-animation:spin 1.2s linear infinite;animation:spin 1.2s linear infinite;transform:translateX(-50%) translateY(-50%);-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-o-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%)}.draggable-item{cursor:move;cursor:grab;cursor:-moz-grab;cursor:-webkit-grab}@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-moz-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-ms-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-o-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}a.card{display:block}a.card:focus,a.card:hover{-webkit-box-shadow:0 7px 15px rgba(0,0,0,.075);-moz-box-shadow:0 7px 15px rgba(0,0,0,.075);box-shadow:0 7px 15px rgba(0,0,0,.075)}.bg-overlay{position:relative;overflow:hidden;color:#f2f2f2}.bg-overlay h1,.bg-overlay h2,.bg-overlay h3,.bg-overlay h4,.bg-overlay h5,.bg-overlay h6{color:#fff}.bg-overlay p{color:#f2f2f2}.bg-overlay:before{position:absolute;background:#0f0f17;opacity:.5;width:100%;height:100%;top:0;left:0;z-index:2}.bg-overlay>div{z-index:3}.bg-overlay .btn-default{color:#fff}.bg-overlay .btn-default:focus,.bg-overlay .btn-default:hover{color:#515365}.bg-overlay.primary:before{background:#6569df;opacity:.6}.bg-overlay.primary-gradient:before{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%);opacity:.8}.bg-overlay.success-gradient:before{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%);opacity:.8}.bg-overlay.info-gradient:before{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%);opacity:.7}.bg-overlay.warning-gradient:before{background:linear-gradient(120deg,#f6d365 0,#fda085 100%);opacity:.7}.bg-overlay.danger-gradient:before{background:linear-gradient(120deg,#f3301a 0,#f37138 100%);opacity:.7}.card-collapse-btn{transition:all .4s ease-in-out;-webkit-transition:all .4s ease-in-out;-moz-transition:all .4s ease-in-out;-o-transition:all .4s ease-in-out;-ms-transition:all .4s ease-in-out}.card-collapse-btn.active{transform:rotate(180deg);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg)}.page-title h1,.page-title h2,.page-title h3,.page-title h4,.page-title h5,.page-title h6,.page-title p,.page-title span{font-size:20px;margin-bottom:25px;margin-top:0}.dropdown.dropdown-animated:not(.scale-left) .dropdown-menu,.dropdown.dropdown-animated:not(.scale-right) .dropdown-menu{opacity:0;visibility:hidden;-webkit-transform:translateY(15px)!important;-moz-transform:translateY(15px)!important;-ms-transform:translateY(15px)!important;transform:translateY(15px)!important;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;display:block;margin:0;top:auto!important}.dropdown.dropdown-animated:not(.scale-left) .dropdown-menu.show,.dropdown.dropdown-animated:not(.scale-right) .dropdown-menu.show{opacity:1;visibility:visible;-webkit-transform:translateY(0)!important;-moz-transform:translateY(0)!important;-ms-transform:translateY(0)!important;transform:translateY(0)!important}.dropdown.dropdown-animated.scale-left .dropdown-menu{-webkit-transform-origin:top right!important;-moz-transform-origin:top right!important;-ms-transform-origin:top right!important;transform-origin:top right!important;transform:scale(0,0)!important;-webkit-transform:scale(0,0)!important;-moz-transform:scale(0,0)!important;-ms-transform:scale(0,0)!important;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;display:block;margin:0;right:0!important;left:auto!important;top:auto!important}.dropdown.dropdown-animated.scale-left .dropdown-menu.show{transform:scale(1,1)!important;-webkit-transform:scale(1,1)!important;-moz-transform:scale(1,1)!important;-ms-transform:scale(1,1)!important}.dropdown.dropdown-animated.scale-right .dropdown-menu{-webkit-transform-origin:top left;-moz-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;transform:scale(0,0)!important;-webkit-transform:scale(0,0)!important;-moz-transform:scale(0,0)!important;-ms-transform:scale(0,0)!important;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;display:block;margin:0;top:auto!important}.dropdown.dropdown-animated.scale-right .dropdown-menu.show{transform:scale(1,1)!important;-webkit-transform:scale(1,1)!important;-moz-transform:scale(1,1)!important;-ms-transform:scale(1,1)!important}.dropdown-menu{border:0;border-radius:0;font-size:14px;min-width:180px;color:#8a8a8a;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.2);-moz-box-shadow:0 2px 5px rgba(0,0,0,.2);box-shadow:0 2px 5px rgba(0,0,0,.2);top:100%}.switch input[type=checkbox]+label:after,.switch input[type=checkbox]+label:before{top:0;left:0;content:"";position:absolute;display:block}.dropdown-menu.dropdown-md{min-width:250px}.dropdown-menu.dropdown-lg{min-width:360px}@media only screen and (max-width:767px){.dropdown-menu.dropdown-lg{min-width:280px}}.dropdown-menu.dropdown-xl{min-width:450px}.dropdown-menu>li.divider{border-bottom:1px solid #e9eaec;height:1px;overflow:hidden}.dropdown-menu>li>a{line-height:1.5;min-height:auto;padding:10px 15px;display:block;transition:all .2s ease-out;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;-ms-transition:all .2s ease-out;color:#8a8a8a}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#515365;text-decoration:none;background-color:#f7f7f8}.dropdown-menu.dropdown-grid{display:flex!important;flex-wrap:wrap;padding:10px}.dropdown-menu.dropdown-grid>li{display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;-webkit-box-pack:center;justify-content:center}.dropdown-menu.dropdown-grid>li>a{padding:10px;border:1px solid #e9eaec;margin:7px;border-radius:4px}.dropdown-menu.dropdown-grid.col-2>li{flex-basis:50%}.dropdown-menu.dropdown-grid.col-3>li{flex-basis:33.333333%}@media only screen and (max-width:767px){.dropdown-menu.dropdown-xl{min-width:280px}.dropdown-menu.dropdown-grid.col-3>li{flex-basis:50%}}.dropdown-menu.dropdown-grid.col-4>li{flex-basis:25%}@media only screen and (max-width:767px){.dropdown-menu.dropdown-grid.col-4>li{flex-basis:50%}}.dropdown-item{line-height:1.5;min-height:auto;padding:10px 20px;display:block;transition:all .15s ease-out;-webkit-transition:all .15s ease-out;-moz-transition:all .15s ease-out;-o-transition:all .15s ease-out;-ms-transition:all .15s ease-out;color:#8a8a8a}.dropdown-item:focus,.dropdown-item:hover{color:#515365;text-decoration:none;background-color:#f7f7f8}.dropdown-item.disabled{opacity:.3;cursor:not-allowed}.dropdown-item.disabled:focus,.dropdown-item.disabled:hover{background-color:transparent}.dropdown-item.active{background-color:#f7f7f8;color:#515365}.dropdown-toggle:after{text-align:center;display:inline;border:0;font-family:Material Design Icons;content:"\F140";line-height:0;vertical-align:middle;position:relative}.dropdown-header{padding:10px 20px;font-weight:500;color:#717171;font-size:15px}.dropdown,.dropup{display:inline-block}.accordion>.card{margin-bottom:15px}.accordion>.card>.card-header{padding:0}.accordion>.card>.card-header>.card-title>a{padding:15px 25px;display:block;color:#515365}.accordion>.card>.card-header>.card-title>a:not(.collapsed):after{transform:rotate(90deg);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-o-transform:rotate(90deg);-ms-transform:rotate(90deg)}.accordion>.card>.card-header>.card-title>a:after{content:"\F142";font-family:"Material Design Icons";float:left;margin-right:10px;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.accordion>.card .card-body{padding-top:5px}.accordion.nested>.card{margin-bottom:0;border-bottom:0}.accordion.nested>.card:last-child{border-bottom:1px solid #e9eaec}.accordion.borderless>.card{margin-bottom:0;border-top:0;border-left:0;border-right:0}.accordion.borderless>.card:last-child{border-bottom:0}.popover{border:1px solid #e9eaec;-webkit-box-shadow:0 9px 12px rgba(0,0,0,.075);-moz-box-shadow:0 9px 12px rgba(0,0,0,.075);box-shadow:0 9px 12px rgba(0,0,0,.075)}.form-control,.page-link:focus{box-shadow:none}.popover-header{background-color:#fafafa;color:#515365;border-bottom:1px solid #e9eaec;border-top-left-radius:0;border-top-right-radius:0}.popover-body{padding:10px 15px;color:#515365}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{border-right-color:#e9eaec}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{border-top-color:#e9eaec}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{border-left-color:#e9eaec}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{border-bottom-color:#e9eaec}.tooltip-inner{background-color:#212224;border-radius:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{border-top-color:#212224}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{border-right-color:#212224}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{border-bottom-color:#212224}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{border-left-color:#212224}.page-link{border:1px solid transparent;border-radius:5px;padding:.4rem .7rem;margin:0 2.5px;color:#8a8a8a;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.input-group-text .checkbox input[type=checkbox]+label:before,.input-group-text .radio input[type=radio]+label:before{margin-right:0}.page-link:hover{color:#24d5d8;text-decoration:none;background-color:transparent;border-color:transparent}.page-item.disabled .page-link{color:#cacaca;border-color:transparent}.page-item.active .page-link{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%);border-color:transparent}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{line-height:1.8;border-color:#e9eaec}.table-sm>tbody>tr>td,.table-sm>tbody>tr>th,.table-sm>tfoot>tr>td,.table-sm>tfoot>tr>th,.table-sm>thead>tr>td,.table-sm>thead>tr>th{padding:7.5px}.table-lg>tbody>tr>td,.table-lg>tbody>tr>th,.table-lg>tfoot>tr>td,.table-lg>tfoot>tr>th,.table-lg>thead>tr>td,.table-lg>thead>tr>th{padding:15px}.table-xl>tbody>tr>td,.table-xl>tbody>tr>th,.table-xl>tfoot>tr>td,.table-xl>tfoot>tr>th,.table-xl>thead>tr>td,.table-xl>thead>tr>th{padding:20px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#fbfbfb}.table-hover>tbody>tr:hover{background-color:#fafafa}.table-bordered{border:1px solid #e9eaec}.table>thead>tr>th{color:#717171;border-bottom:1px solid #e9eaec}.table .thead-dark th{background-color:#515365;border-color:#515365}.table .thead-light th,.table tr.selected{background-color:#fafafa}.table .thead-light th{border-color:#e9eaec;color:#717171}.table td,.table th{vertical-align:middle}.form-control:disabled,.form-control[readonly],.input-group-text{background-color:#f4f4f5}@media only screen and (max-width:992px){.table-overflow{width:100%;overflow-x:auto}}.form-group{margin-bottom:25px}.form-group label.control-label{display:inline-block;margin-bottom:.5rem;font-size:13px;font-weight:500;text-transform:uppercase}.checkbox input[type=checkbox]+label:before,.radio input[type=radio]+label:before{width:22px;height:22px;font-family:'Material Design Icons';font-weight:400;vertical-align:bottom;text-align:center}.form-group label.col-form-label{margin-bottom:0;line-height:1.5;padding-top:calc(.75rem + 1px);padding-bottom:calc(.75rem + 1px)}.form-control{border:1px solid #e4e5e7;border-radius:5px;line-height:2.2;font-size:14px;color:#8a8a8a;transition:all .2s ease-in;-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;-o-transition:all .2s ease-in;-ms-transition:all .2s ease-in}.form-control::-webkit-input-placeholder{color:#bdbdbd}.form-control:-moz-placeholder{color:#bdbdbd}.form-control::-moz-placeholder{color:#bdbdbd}.form-control:-ms-input-placeholder{color:#bdbdbd}.form-control:focus{outline:0;-webkit-box-shadow:1px 1px 15px rgba(0,0,0,.075);-moz-box-shadow:1px 1px 15px rgba(0,0,0,.075);box-shadow:1px 1px 15px rgba(0,0,0,.075);border-color:#24d5d8}.form-control.error{border-color:#fd3259}.form-control:disabled:focus,.form-control[readonly]:focus{border-color:#e9eaec}.form-control:disabled{cursor:not-allowed}.form-control-plaintext{padding-top:.375rem;padding-bottom:.375rem;line-height:2.2}.form-text{margin-top:5px;color:#979797}.form-control-sm,.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:.15rem .75rem}.form-control-lg,.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:.7rem .75rem}.icon-input{position:relative}.icon-input>.form-control{padding-left:50px;padding-right:50px}.icon-input>i{position:absolute;top:0;left:15px;font-size:20px;padding-top:10px;line-height:1;color:#bdbdbd}.input-group-text .checkbox,.input-group-text .radio{padding:0}.input-group>.input-group-append>.btn,.input-group>.input-group-prepend>.btn{margin:0}.input-group>.input-group-append.dropdown,.input-group>.input-group-prepend.dropdown{display:flex}.input-group-text{border:1px solid #e4e5e7;color:#a4a4a4}.textarea-md{min-height:150px}.textarea-lg{min-height:250px}.checkbox,.radio{min-height:auto;position:relative}.checkbox{padding:10px 0}.checkbox input[type=checkbox]{margin:0;display:none;width:22px}.checkbox input[type=checkbox]+label{padding-left:0}.checkbox input[type=checkbox]+label:before{content:"\F12C";display:inline-block;margin-right:10px;border:2px solid #e9eaec;border-radius:3px;font-size:15px;line-height:19px;background:#fff;color:transparent;cursor:pointer;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.checkbox input[type=checkbox]:checked+label:before{background:#24d5d8;border-color:#24d5d8;color:#fff}.checkbox input[type=checkbox].disabled+label:before,.checkbox input[type=checkbox]:disabled+label:before{cursor:not-allowed}.checkbox input[type=checkbox].error+label:before{border-color:#ffd0d9}.checkbox.to-do input[type=checkbox]:checked+label{text-decoration:line-through}.checkbox.checkbox-primary input[type=checkbox]:checked+label:before{background:#6569df;border-color:#6569df;color:#fff}.checkbox.checkbox-info input[type=checkbox]:checked+label:before{background:#04a1f4;border-color:#04a1f4;color:#fff}.checkbox.checkbox-warning input[type=checkbox]:checked+label:before{background:#fecd2f;border-color:#fecd2f;color:#fff}.checkbox.checkbox-danger input[type=checkbox]:checked+label:before{background:#fd3259;border-color:#fd3259;color:#fff}.radio{padding:10px 0}.radio input[type=radio]{margin:0;display:none;width:22px}.radio input[type=radio]+label{padding-left:0}.radio input[type=radio]+label:before{content:"\F12F";display:inline-block;margin-right:10px;border:2px solid #e9eaec;border-radius:50%;font-size:11px;line-height:18px;background-color:#fff;color:transparent;cursor:pointer;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.radio input[type=radio]:checked+label:before{color:#24d5d8;border-color:#24d5d8}.radio input[type=radio].disabled+label:before,.radio input[type=radio]:disabled+label:before{cursor:not-allowed}.radio.radio-primary input[type=radio]:checked+label:before{color:#6569df;border-color:#6569df}.radio.radio-info input[type=radio]:checked+label:before{color:#04a1f4;border-color:#04a1f4}.radio.radio-warning input[type=radio]:checked+label:before{color:#fecd2f;border-color:#fecd2f}.radio.radio-danger input[type=radio]:checked+label:before{color:#fd3259;border-color:#fd3259}.checkbox label,.radio label{cursor:pointer}.switch input[type=checkbox]{opacity:0;position:absolute}.switch input[type=checkbox]+label{position:relative;display:inline-block;transition:.4s ease;-webkit-transition:.4s ease;-moz-transition:.4s ease;-o-transition:.4s ease;-ms-transition:.4s ease;height:20px;width:35px;border:1px solid #e9eaec;border-radius:60px;cursor:pointer}.switch input[type=checkbox]+label:before{transition:.2s cubic-bezier(.24,0,.5,1);-webkit-transition:.2s cubic-bezier(.24,0,.5,1);-moz-transition:.2s cubic-bezier(.24,0,.5,1);-o-transition:.2s cubic-bezier(.24,0,.5,1);-ms-transition:.2s cubic-bezier(.24,0,.5,1);height:20px;width:35px;border-radius:30px}.switch input[type=checkbox]+label:after{box-shadow:0 0 0 1px rgba(0,0,0,.1),0 4px 0 0 rgba(0,0,0,.04),0 4px 9px rgba(0,0,0,.13),0 3px 3px rgba(0,0,0,.05);transition:.35s cubic-bezier(.54,1.6,.5,1);-webkit-transition:.35s cubic-bezier(.54,1.6,.5,1);-moz-transition:.35s cubic-bezier(.54,1.6,.5,1);-o-transition:.35s cubic-bezier(.54,1.6,.5,1);-ms-transition:.35s cubic-bezier(.54,1.6,.5,1);background:#f7f7f7;height:19px;width:19px;border-radius:60px}.switch input[type=checkbox]:checked+label:before{background:#24d5d8;transition:width .2s cubic-bezier(0,0,0,.1);-webkit-transition:width .2s cubic-bezier(0,0,0,.1);-moz-transition:width .2s cubic-bezier(0,0,0,.1);-o-transition:width .2s cubic-bezier(0,0,0,.1);-ms-transition:width .2s cubic-bezier(0,0,0,.1)}.switch input[type=checkbox]:checked+label:after{left:16px}.switch input[type=checkbox]:disabled+label{opacity:.7;cursor:not-allowed}.switch.switch-primary input[type=checkbox]:checked+label:before{background:#6569df}.switch.switch-info input[type=checkbox]:checked+label:before{background:#04a1f4}.switch.switch-warning input[type=checkbox]:checked+label:before{background:#fecd2f}.switch.switch-danger input[type=checkbox]:checked+label:before{background:#fd3259}.test-wrapper{padding:0;margin:0;overflow:auto;min-height:100%;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out;border:1px solid #e9eaec}@media only screen and (max-width:992px){.test-wrapper{position:absolute;left:0;width:100%}}.test-wrapper .test-list{position:relative;padding:0;width:100%;overflow-y:hidden;background-color:#fff}@media only screen and (min-width:992px){.test-wrapper .test-list{width:25%;border-right:1px solid #e9eaec;float:left}.test-wrapper .test-list .test-list-wrapper{height:calc(100vh - 65px - 115px - 41px)}}@media only screen and (min-width:992px) and (max-width:1440px){.test-wrapper .test-list{width:35%}}.test-wrapper .test-list .test-list-tools{padding:5px 15px;border-bottom:1px solid #e9eaec;text-align:right;display:block}.test-wrapper .test-list .test-list-tools .tools{list-style:none;padding:0}.test-wrapper .test-list .test-list-tools .tools>li{display:inline-block;padding:3px 5px}.test-wrapper .test-list .test-list-tools .tools>li>a{font-size:16px;color:#8a8a8a;display:block;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.test-wrapper .test-list .test-list-tools .tools>li>a:focus,.test-wrapper .test-list .test-list-tools .tools>li>a:hover{color:#24d5d8}.test-wrapper .test-list .test-list-wrapper{position:relative;overflow-y:auto}.test-wrapper .test-list .test-list-wrapper .test-list-item{padding-left:0;list-style:none}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item{position:relative;display:table;width:100%;padding:15px;border-bottom:1px solid #e9eaec;cursor:pointer;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item:focus,.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item:hover{background-color:#fafafa}@media only screen and (min-width:992px){.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item.active{background-color:#fafafa}}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item a{color:#8a8a8a}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-avatar{position:absolute;top:20px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-avatar img{width:30px;height:30px;border-radius:50px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail{vertical-align:top;display:table-cell;width:100%;padding-left:45px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail p{margin-bottom:0}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail .name{font-size:16px;color:#515365}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail .subject{color:#515365;font-weight:500;margin-bottom:5px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail .datetime{position:absolute;top:20px;right:15px;font-size:11px}.test-wrapper .test-content{float:left;width:75%;position:relative;padding:0;background-color:#fff;height:calc(100vh - 65px - 115px);overflow:auto;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.test-wrapper .test-content.no-inbox-view{width:100%}@media only screen and (min-width:992px) and (max-width:1440px){.test-wrapper .test-content{width:65%}}@media only screen and (max-width:992px){.test-wrapper .test-content{position:fixed;width:100%;height:calc(100vh - 65px);top:calc(65px + 20px);left:-100%}.test-wrapper .test-content.open{left:0}}.test-wrapper .test-content .test-content-tools{padding:10px 15px;border-bottom:1px solid #e9eaec}@media only screen and (min-width:992px){.test-wrapper .test-content .test-content-tools{display:none}}.test-wrapper .test-content .test-content-tools ul{list-style:none;padding:0;display:inline-block}.test-wrapper .test-content .test-content-tools ul li{display:inline-block}.test-wrapper .test-content .test-content-tools ul li a{font-size:16px;padding:0 10px;color:#8a8a8a}.test-wrapper .test-content .test-content-tools ul li a:focus,.test-wrapper .test-content .test-content-tools ul li a:hover{color:#24d5d8}.test-wrapper .test-content .test-content-detail{position:relative;padding:30px;max-height:calc(100vh - 65px)}@media only screen and (max-width:992px){.test-wrapper .test-content .test-content-detail{padding:15px}.mail-nav-active .sec-side-nav{left:0}}.test-wrapper .test-content .test-content-detail .detail-head{position:relative}.test-wrapper .test-content .test-content-detail .detail-head .thumb-img{width:50px;height:50px}.test-wrapper .test-content .test-content-detail .detail-head .info{height:50px;padding-left:65px}.test-wrapper .test-content .test-content-detail .detail-head .info .title{padding-top:5px}.test-wrapper .test-content .test-content-detail .detail-head .info .sub-title{max-width:100%}.test-wrapper .test-content .test-content-detail .detail-head .tools{padding:0;list-style:none;float:right;margin-top:15px}.test-wrapper .test-content .test-content-detail .detail-head .tools>li{display:inline-block;padding:10px}.test-wrapper .test-content .test-content-detail .detail-head .tools>li a{color:#8a8a8a}.test-wrapper .test-content .test-content-detail .detail-head .tools>li a:focus,.test-wrapper .test-content .test-content-detail .detail-head .tools>li a:hover{color:#515365}.test-wrapper .test-content .test-content-detail .detail-body{padding:25px 30px;position:relative}.test-wrapper .test-content .test-content-detail .detail-foot{padding:15px 30px}.test-wrapper .test-content .test-content-detail .detail-foot .attachments{list-style:none;padding-left:0}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li{display:inline-block;border:1px solid #e9eaec;margin-right:10px;margin-bottom:10px;border-radius:6px}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a{display:block;color:#8a8a8a}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-icon{float:left;padding:8px 15px;font-size:28px;border-right:1px solid #e9eaec}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-info{display:inline-block;padding:8px 15px 8px 10px}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-info .file-name,.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-info .file-size{display:block}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:focus,.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:hover{color:#515365}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:focus .file-icon,.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:hover .file-icon{color:#24d5d8}.test-wrapper .email-compose{position:relative}.test-wrapper .email-compose .email-compose-tools{background-color:#fafafa;padding:10px 15px;border-bottom:1px solid #e9eaec}@media only screen and (min-width:992px){.test-wrapper .email-compose .email-compose-tools{display:none}}.test-wrapper .email-compose .email-compose-tools ul{list-style:none;padding:0;display:inline-block}.test-wrapper .email-compose .email-compose-tools ul li{display:inline-block}.test-wrapper .email-compose .email-compose-tools ul li a{font-size:16px;padding:0 10px;color:#8a8a8a}.test-wrapper .email-compose .email-compose-tools ul li a:focus,.test-wrapper .email-compose .email-compose-tools ul li a:hover{color:#24d5d8}.test-wrapper .email-compose .email-compose-body{padding:30px 20px}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input{box-shadow:none;border:0;border-bottom:1px solid #e9eaec;font-size:14px;padding:12px}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input::-webkit-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input:-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input::-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input:-ms-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject{border:0;padding:12px}.test-wrapper .email-compose .email-compose-body .send-header .subject::-webkit-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject:-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject::-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject:-ms-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .note-editor{margin-top:5px}.test-wrapper .email-compose .email-compose-body .note-editor.note-frame .note-statusbar{display:none}.test-wrapper .email-compose .email-compose-body .note-editor .panel-heading.note-toolbar{position:absolute;z-index:9;width:100%;bottom:0;border-bottom:0;border-top:1px solid #e9eaec}@media only screen and (max-width:992px){.mail-nav-active .test-wrapper{left:200px}} + + + /** + * Featherlight - ultra slim jQuery lightbox + * Version 1.5.0 - http://noelboss.github.io/featherlight/ + * + * Copyright 2016, Noël Raoul Bossart (http://www.noelboss.com) + * MIT Licensed. +**/ +@media all{.featherlight{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:2147483647;text-align:center;white-space:nowrap;cursor:pointer;background:#333;background:rgba(0,0,0,0)}.featherlight:last-of-type{background:rgba(0,0,0,.8)}.featherlight:before{content:'';display:inline-block;height:100%;vertical-align:middle;margin-right:-.25em}.featherlight .featherlight-content{position:relative;text-align:left;vertical-align:middle;display:inline-block;overflow:auto;padding:25px 25px 0;border-bottom:25px solid transparent;margin-left:5%;margin-right:5%;max-height:95%;background:#fff;cursor:auto;white-space:normal}.featherlight .featherlight-inner{display:block}.featherlight .featherlight-close-icon{position:absolute;z-index:9999;top:0;right:0;line-height:25px;width:25px;cursor:pointer;text-align:center;font-family:Arial,sans-serif;background:#fff;background:rgba(255,255,255,.3);color:#000}.featherlight .featherlight-image{width:100%}.featherlight-iframe .featherlight-content{border-bottom:0;padding:0}.featherlight iframe{border:0}.featherlight *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}}@media only screen and (max-width:1024px){.featherlight .featherlight-content{margin-left:10px;margin-right:10px;max-height:98%;padding:10px 10px 0;border-bottom:10px solid transparent}} + + + + +/** + * json-tree + * Copyright (c) 2013 Leonardo Menezes + * https://github.com/lmenezes/json-tree + * MIT Licensed. + */ +.jstBracket,.jstComma,.jstValue{white-space:pre-wrap}.jstValue{font-size:10px;font-weight:400;font-family:"Lucida Console",Monaco,monospace}.jstProperty{color:#666;word-wrap:break-word}.jstBool{color:#2525CC}.jstNum{color:#D036D0}.jstNull{color:gray}.jstStr{color:#2DB669}.jstFold:after{content:' -';cursor:pointer}.jstExpand{white-space:normal}.jstExpand:after{content:' +';cursor:pointer}.jstFolded{white-space:normal!important}.jstHiddenBlock{display:none} + + + +/** + * Extent Framework, Version 4, Spark, HtmlReporter + * AventStack + * Licender under Apache 2.0 + **/ + +body, p { + font-family: Roboto,-apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif; + color: #585858; +} +h5 { + font-size: 16px; + font-weight: 500; +} +table > thead > tr > th { + font-weight: 500 !important; + font-size: 11px; + text-transform: uppercase; +} +td { + word-break: break-all; +} + + +/** + * Sidenav + * +**/ +.side-nav-controls { + position: absolute; + left: -15px; + bottom: 10px; +} +.side-nav-controls li { + list-style: none; +} + + +/** + * Wrappers + * +**/ +.page-container .main-content { + padding: 62px 0 0; + min-height: calc(100vh); +} +.test-wrapper { + border-left: none !important; +} +.test-wrapper .test-content { + height: calc(100vh - 64px); +} +.test-list-item { + margin-bottom: 50px; +} +.side-nav { + background-color: transparent; +} + + +/** + * base classes + * +**/ +.text-sm { + font-size: 11px; +} +.form-control, .form-control:focus { + color: #ccc; +} +.dropdown-toggle:after { + display: none; +} +.box-height-150 { + height: 150px !important; +} + +/** + * Test Content + * +**/ + +/* test list */ +.test-wrapper .test-list { + background: #fff; +} +.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail { + display: block; + padding-left: 5px; +} +.test-view .test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail { + padding-left: 40px; +} +.status-avatar { + width: 20px; + height: 20px; + border-radius: 100%; + text-align: center; + vertical-align: middle; + color: #000; + font-size: 11px; + font-weight: 500; + padding-top: 1px; + text-transform: lowercase; +} +.test-view .status-avatar { + position: absolute; + padding-top: 3px; + top: 18px; +} +.accordion .status-avatar { + top: 20px; + position: relative; + right: 20px; +} +.test-detail .name { + font-size: 14px !important; + font-weight: 500; + word-break: break-all; + width: 80%; +} + +/* attributes-view */ +.attributes-view .info > span { + cursor: pointer; +} + +/* bdd-report */ +.bdd-report .accordion .status-avatar { + right: 0; +} +.bdd-report .node { + padding: 20px 15px 0; +} +.bdd-report .card .card-body { + padding: 0 16px 20px 16px; +} +.bdd-report .accordion .node { + font-size: 14px; +} +.bdd-report .accordion .node-description { + font-weight: 400; + padding-left: 40px; +} +.bdd-report .accordion>.card>.card-header { + padding-bottom: 20px; +} +.given, .when, .then, .and, .asterisk, .but { + font-weight: 400; + padding-top: 10px; +} +.bdd-report .alert-icon { + font-size: 11px; + border-radius: 100%; + padding: 0; + height: 20px; + width: 20px; + margin-right: 15px; +} +.bdd-report .alert-icon > i { + padding-left: 4px; + padding-top: 4px; +} +.bdd-report .alert-icon > i.fa-times { + padding-left: 6px; +} +.bdd-report .details, .bdd-report .code-block { + margin-left: 35px; +} +.bdd-report .code-block { + width: 95%; +} +.bdd-report .scenario_outline { + padding: 10px 20px 0; +} +.bdd-report .scenario_outline .card-header { + padding: 0; + min-height: auto !important; +} +.bdd-report .scenario_outline .card-header .node { + padding: 0; +} +.bdd-report .scenario_outline .card-header .status-avatar { + top: 2px; + margin-right: 15px; +} +.bdd-report .scenario { + font-weight: 500; +} +.bdd-report .card-body.l1 { + border: 1px solid rgba(0,0,0,.125); + margin-bottom: 20px; + padding-top: 15px; +} +.bdd-report .card-body.l1 .card-body { + padding: 0; +} + +/* content */ +.test-wrapper .test-content .test-content-detail { + padding: 30px 20px; +} +.test-wrapper .test-content .test-content-detail .detail-head .info { + padding-left: 0; +} +.test-wrapper .test-content .test-content-detail .detail-body { + padding: 0; +} +.test-wrapper .test-content .test-content-detail .detail-foot { + padding: 15px 0; +} +pre, .code-block { + background-color: #f8f9fa; + border: 1px solid #ebedef; + border-radius: 4px; + color: #222 !important; + font-family: Consolas,monospace; + font-size: 13px; + margin: 0; + padding: 7px 10px; + white-space: pre-wrap; +} +textarea { + resize: auto; + width: 100%; +} +.status-col { + width: 70px; +} +.timestamp-col { + width: 110px; +} +img.r-img { + width: 5%; +} + +/* nodes */ +.card > .accordion { + margin-left: 20px; + margin-right: 20px; +} +.detail-body + .accordion { + margin-top: -20px; +} +.card-header .card-title { + display: block; + cursor: pointer; +} +.card .card-body { + padding: 20px; +} +.node + a { + float: right !important; +} +.node { + display: inline-block; + padding: 20px; + font-size: 14px; + font-weight: 500; +} +.accordion > .card > .card-header > .card-title > a:not(.collapsed):after { + display: none; +} +.card-body .description { + margin-top: -20px; + margin-bottom: 20px; + font-size: 90%; +} + +/* status */ +.log-status { + border-radius: 100%; +} +.item-meta .badge { + font-size: 11px; +} +.transparent-bg { + background-color:transparent !important; +} +.text-fail,.text-fatal { + color:#ff5722 !important; +} +.text-error { + color:#ff9800 !important; +} +.text-warning { + color:#ffc107 !important; +} +.text-info { + color:#00bcd4 !important; +} +.text-skip { + color: #64b5f6 !important; +} +.text-pass { + color: #1c965b !important; +} +.fail-bg, .fatal-bg,.avatar.fail,.avatar.fatal { + background: #e57373; +} +.pass-bg,.avatar.pass { + background: #9ccc65; +} +.skip-bg,.avatar.skip { + background: #64b5f6; +} +.error-bg,.avatar.skip { + background: #ffd54f; +} +.warn-bg,.avatar.warn,.warning-bg,.avatar.warning { + background: #ffc107; +} +.b-skip { + border-color: #64b5f6; +} +.badge.status { + background: transparent !important; +} + +/* jsonTree */ +.jstValue { + font-size: 11px; +} +.jstProperty, .jstFold { + color: #444; +} +.dark .jstProperty, .dark .jstFold { + color: #eee; +} +.jstStr { + color: #00b300; +} +.dark .jstStr { + color: #7ffaaa; +} +.dark .jstBool { + color: #668cff; +} +.dark .jstNum { + color: #ff66ff; +} + + +/** + * Themes + * +**/ + +.dark .header { + background-color: #08111c; +} +.dark .side-nav, .dark .test-list { + background-color: #19222d !important; + border-right: none; +} +.dark .test-wrapper { + border: none; +} +.dark .test-item, .dark .test-list-tools, .dark .header { + border-bottom: 1px solid #19222d !important; +} +.dark .table>thead>tr>th, .dark .table>tbody>tr>td { + border-bottom: 1px solid #494949; +} +.dark .table>thead>tr>th, .dark .table>tbody>tr>td, .dark .card-footer, .dark td, .dark th { + border-top: 1px solid #494949; +} +.dark .test-item.active, .dark .test-item:hover { + background-color: #19221c !important; +} +.dark .test-detail .name { + color: rgba(141,164,191,.95) !important; +} +.dark .test-wrapper, .dark .test-content, .dark.dashboard-view .container-fluid { + background-color: #243140; +} +.dark .card, .dark .attachments>li, .dark .badge-default { + color: rgba(141,164,191,.95) !important; + border: 1px solid #494949 !important; +} +.dark .card, .dark tr.bg-gray, .dark .table, .dark table, dark tr, .dark th, .dark td, .dark .table-striped>tbody>tr:nth-of-type(odd) { + background-color: transparent !important; +} +.dark .side-nav .side-nav-inner .side-nav-menu, .dark .file-icon { + border-right: 1px solid #494949 !important; +} +.dark .node { + color: #999; +} +.dark, .dark .table>thead>tr>th, .dark h1, .dark h2, .dark h3, .dark h4, .dark .font-weight-light, .dark .card-title, .dark .detail-head h4 { + color: #999; +} +.dark pre, .dark .code-block { + background: transparent; + border: 1px solid #555; + color: rgba(180,200,220,.95) !important; +} + +@media only screen and (min-width: 992px) { + .test-wrapper .test-list .test-list-wrapper { + height: calc(100vh - 106px); + } + .test-wrapper .test-list { + width: 32%; + } + .test-wrapper .test-content { + width: 68%; + } +} +@media only screen and (max-width: 992px) { + .test-wrapper .test-content.open { + top: 65px; + } +} diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js new file mode 100644 index 0000000..0ba3b62 --- /dev/null +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js @@ -0,0 +1,199 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,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"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" +<#if offline=="true"> + + <#else> + + <#if config.containsKey("scripts") && config.getValue("scripts")?has_content> <#include "../../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl index 510a085..718f1b5 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl @@ -12,7 +12,11 @@ <#include "partials/head.ftl"> - +<#if offline=="true"> + +<#else> + +
diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-head.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-head.ftl index 66291af..5f12ef1 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-head.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-head.ftl @@ -5,9 +5,14 @@ - - - + <#if offline=="true"> + + + <#else> + + + + ${ config.getValue('documentTitle') } diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl index c454df8..c5a3216 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl @@ -42,6 +42,8 @@ <#assign cdnURI="extentreports.com/resx" csscommit="" jscommit=""> +<#include "../commons/commons-variables.ftl"> + <#include 'v3-html-head.ftl'> @@ -112,10 +114,11 @@ }; - <#if config.getValue('offline')?string == 'true'> - + + <#if offline=="true"> + <#else> - + <#assign hide=(chartVisibleOnOpen=='true')?then(false, true)> <#if hide> From 65cdf748142eb2270888b63292ef6fd0c0e7969b Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 7 Feb 2019 12:35:04 -0500 Subject: [PATCH 04/77] fixes #50 --- .../com/aventstack/extentreports/view/spark/partials/head.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl index d852357..c11f164 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl @@ -1,4 +1,4 @@ -<#assign resourceCDN=config.getValue('resourceCDN') cdnURI="cdn.rawgit.com/extent-framework/extent-github-cdn/" csscommit="24cb10e" jscommit="24cb10e" iconcommit="d74480e"> +<#assign resourceCDN=config.getValue('resourceCDN') cdnURI="cdn.rawgit.com/extent-framework/extent-github-cdn/" csscommit="9be0dad" jscommit="24cb10e" iconcommit="d74480e"> <#if resourceCDN=="extentreports"> <#assign cdnURI="extentreports.com/resx" csscommit="" jscommit="" iconcommit=""> From 5fe5716e666de6ba438d21bc5fa07d4abb27ef95 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 7 Feb 2019 14:38:19 -0500 Subject: [PATCH 05/77] fixes #51 --- .../view/v3html/dashboard-view/v3-html-dashboard-view.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/dashboard-view/v3-html-dashboard-view.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/dashboard-view/v3-html-dashboard-view.ftl index 2eb1c8e..f995b83 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/dashboard-view/v3-html-dashboard-view.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/dashboard-view/v3-html-dashboard-view.ftl @@ -73,7 +73,7 @@ Name Passed Failed - Others + Skipped Passed % <#list categoryContext as category> @@ -81,7 +81,7 @@ ${category.name} ${category.passed} ${category.failed} - ${category.others} + ${category.skipped} <#if category.size()!=0> ${(category.passed/category.size())*100}% From ae36cd510e512d030c3ec6e14c0d087ec5f7af6f Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 8 Feb 2019 12:12:57 -0500 Subject: [PATCH 06/77] closes #47 --- .../extentreports/offline/spark/js/spark-script.js | 9 +++++++++ .../extentreports/offline/v3html/js/v3html-script.js | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js index 0ba3b62..8cf8703 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js @@ -72,6 +72,15 @@ $(".test-item").click(function() { $(".test-item").removeClass("active"); var content = $(this).addClass("active").find(".test-contents").clone(); $(".test-content-detail .detail-body").empty().append(content.removeClass("d-none")); + + var loc = window.location.href; + if (loc.indexOf("test-name")>0) { + var name = loc.match(/test-name.*/)[0].replace("test-name=", ""); + name = name.replace(/%22/g, "").replace(/%20/, " "); + $(".test-detail .name").filter(function() { + return $(this).text() == name; + }).closest(".test-item").click(); + } }); $(document).ready(function() { diff --git a/src/main/resources/com/aventstack/extentreports/offline/v3html/js/v3html-script.js b/src/main/resources/com/aventstack/extentreports/offline/v3html/js/v3html-script.js index 7837c55..e9765b0 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/v3html/js/v3html-script.js +++ b/src/main/resources/com/aventstack/extentreports/offline/v3html/js/v3html-script.js @@ -57,6 +57,15 @@ $(document).ready(function() { $('#exception-collection .exception').dynamicTestSearch('#exception-view #search-tests'); $("#timeline-chart").addClass("hide"); + + var loc = window.location.href; + if (loc.indexOf("test-name")>0) { + var name = loc.match(/test-name.*/)[0].replace("test-name=", ""); + name = name.replace(/%22/g, "").replace(/%20/, " "); + $(".test-name").filter(function() { + return $(this).text() == name; + }).click(); + } }); /* -- [ sidenav - toggle views ] -- */ From b6bd55587faa1b4865edd06107d40b7e362fc432 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Wed, 20 Feb 2019 16:05:42 -0800 Subject: [PATCH 07/77] fixes #56 --- .../java/com/aventstack/extentreports/ExtentObservable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 266dbb5..b7844d7 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -265,7 +265,7 @@ private void refreshReportStats() { /** * Refresh and notify all reports of distinct status assigned to tests */ - private void refreshStatusList() { + private synchronized void refreshStatusList() { statusMap.clear(); statusList.clear(); refreshStatusList(testList); @@ -277,7 +277,7 @@ private void refreshStatusList() { * * @param list a list of started {@link Test} */ - private void refreshStatusList(List list) { + private synchronized void refreshStatusList(List list) { if (list == null || list.isEmpty()) return; From 659443032ce72e81436ca7d1c55c00de7cda0821 Mon Sep 17 00:00:00 2001 From: Virender Singh Date: Tue, 26 Feb 2019 21:41:52 +0530 Subject: [PATCH 08/77] Changing the implementation of ConfigMap to be backed by a java.util.map instead of a list --- .../externalconfig/ConfigLoader.java | 7 +- .../externalconfig/model/ConfigMap.java | 89 ++++++----- .../aventstack/extentreports/model/Test.java | 2 +- .../reporter/BasicFileReporter.java | 5 +- .../reporter/ConfigurableReporter.java | 143 +++++++++--------- .../reporter/ExtentKlovReporter.java | 27 ++-- ...tmlBasicFileReporterConfigurationTest.java | 2 +- .../HtmlConfigurableReporterTest.java | 15 +- ...erBasicFileReporterConfigurationTest2.java | 2 +- 9 files changed, 144 insertions(+), 148 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java b/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java index e9be842..e8fbd84 100644 --- a/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java +++ b/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java @@ -87,12 +87,7 @@ public ConfigMap getConfigurationHash() { value = el instanceof CharacterData ? ((CharacterData) el).getData() : value; - - Config c = new Config(); - c.setKey(el.getNodeName()); - c.setValue(value); - - configContext.setConfig(c); + configContext.setConfig(el.getNodeName(), value); } } diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java b/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java index 258a669..889013c 100644 --- a/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java +++ b/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java @@ -1,43 +1,56 @@ package com.aventstack.extentreports.externalconfig.model; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.HashMap; +import java.util.Map; public class ConfigMap { - - private List configList; - - public ConfigMap() { - configList = new ArrayList<>(); - } - - public void setConfig(Config c) { - if (containsKey(c.getKey())) - removeKey(c.getKey()); - - configList.add(c); - } - - public List getConfigList() { return configList; } - - public boolean containsKey(String k) { - return configList.stream() - .anyMatch(x -> x.getKey().equals(k)); - } - - void removeKey(String k) { - configList.removeIf(x -> x.getKey().equals(k)); - } - - public Object getValue(String k) { - Optional c = configList.stream() - .filter(x -> x.getKey().equals(k)) - .findFirst(); - - if (c.isPresent()) - return c.get().getValue(); - - return null; - } + + private Map configMap; + + public ConfigMap() { + configMap = new HashMap(); + } + + public void setConfig(String key, Object value) { + configMap.put(key, value); + } + + public Map getConfigMap() { + return configMap; + } + + public boolean containsKey(String k) { + return configMap.containsKey(k); + } + + void removeKey(String k) { + configMap.remove(k); + } + + public Object getValue(String k) { + return configMap.containsKey(k) ? configMap.get(k) : null; + } + + public void appendConfig(Map configurations) + { + // This might create a hard dependency on Java 8. As Lambda function were introduced in Java *. + // We can instead have an in-line implementation of BiConsumer interface + configurations.forEach((key, value) -> this.setConfig(key, value)); + } + + public void appendConfig(ConfigMap configurations) + { + Map map = configurations.configMap; + this.appendConfig(map); + } + + + public boolean isEmpty() { + return configMap.isEmpty(); + } + + public void printMapForTest() + { + configMap.forEach((key, value) -> System.out.println("Key: " + key + " value: " + String.valueOf(value))); + } } diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index 9ae3719..b1b8f97 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -200,7 +200,7 @@ public AbstractStructure getNodeContext() { } public boolean hasChildren() { - return node != null && node.getAll() != null && node.getAll().size() > 0; + return node != null && !node.isEmpty(); } public void setStartTime(Date startTime) { diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index f9c2257..fa98ef2 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -120,10 +120,7 @@ protected void init(String[] configFilePath, BasicFileConfiguration userConfig) protected void loadUserConfig() { for (Map.Entry entry : userConfig.getConfigMap().entrySet()) { if (entry.getValue() != null) { - Config c = new Config(); - c.setKey(entry.getKey()); - c.setValue(entry.getValue()); - configContext.setConfig(c); + configContext.setConfig(entry.getKey().toString(), entry.getValue()); } } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java index 1f4359b..13a114b 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java @@ -15,108 +15,105 @@ import com.aventstack.extentreports.externalconfig.model.ConfigMap; /** - * A base class to provide bootstrapping for loading custom configuration for the Reporter - * using XML or Properties file + * A base class to provide bootstrapping for loading custom configuration for + * the Reporter using XML or Properties file * */ -public abstract class ConfigurableReporter - implements ExtentReporter { +public abstract class ConfigurableReporter implements ExtentReporter { private static final Logger logger = Logger.getLogger(ConfigurableReporter.class.getName()); - + /** - * A key-value pair holding information from default and the - * user-provided configuration + * A key-value pair holding information from default and the user-provided + * configuration */ protected ConfigMap configContext = new ConfigMap(); - + /** * Loads configuration from an XML file * * @param filePath Configuration file path - * @param silent Load configuration silently, no errors are thrown if the configuration file is not present + * @param silent Load configuration silently, no errors are thrown if the + * configuration file is not present */ public void loadXMLConfig(String filePath, Boolean silent) { - loadXMLConfig(new File(filePath), silent); - } - + loadXMLConfig(new File(filePath), silent); + } + /** * Loads configuration from an XML file * * @param filePath configuration file path */ - public void loadXMLConfig(String filePath) { - loadXMLConfig(filePath, false); - } - + public void loadXMLConfig(String filePath) { + loadXMLConfig(filePath, false); + } + /** * Loads configuration from an XML file * - * @param file configuration {@link File} + * @param file configuration {@link File} * @param silent If silent, no errors will be thrown */ public void loadXMLConfig(File file, Boolean silent) { - ConfigLoader configLoader = new ConfigLoader(file, silent); - ConfigMap config = configLoader.getConfigurationHash(); - - if (config != null) - config.getConfigList().forEach(configContext::setConfig); - } - - /** - * Loads configuration from a Properties file - * - * @param properties a {@link Properties} object - */ - public void loadConfig(Properties properties) { - properties.entrySet().forEach(o -> { - Config c = new Config(); - c.setKey(o.getKey().toString()); - c.setValue(o.getValue()); - configContext.setConfig(c); - }); - } - - /** - * Loads configuration from an {@link InputStream} which is a - * {@link Properties} file - * - * @param stream an {@link InputStream} - */ + ConfigLoader configLoader = new ConfigLoader(file, silent); + ConfigMap config = configLoader.getConfigurationHash(); + configContext.appendConfig(config); + } + + /** + * Loads configuration from a Properties file + * + * @param properties a {@link Properties} object + */ + public void loadConfig(Properties properties) { + properties.entrySet().forEach(o -> { + if (o.getKey() != null) { + configContext.setConfig(o.getKey().toString(), o.getValue()); + } + }); + } + + /** + * Loads configuration from an {@link InputStream} which is a {@link Properties} + * file + * + * @param stream an {@link InputStream} + */ public void loadConfig(InputStream stream) { - Properties properties = new Properties(); - - try { - properties.load(stream); - loadConfig(properties); - } catch (FileNotFoundException e) { - logger.log(Level.SEVERE, "Default Properties file not found", e); - } catch (IOException e) { - logger.log(Level.SEVERE, "Unable to load properties file", e); - } - } - + Properties properties = new Properties(); + + try { + properties.load(stream); + loadConfig(properties); + } catch (FileNotFoundException e) { + logger.log(Level.SEVERE, "Default Properties file not found", e); + } catch (IOException e) { + logger.log(Level.SEVERE, "Unable to load properties file", e); + } + } + /** - * Loads configuration from an path which is a {@link Properties} file - * - * @param filePath Properties file path - */ - public void loadConfig(String filePath) { - try { - InputStream is = new FileInputStream(filePath); - loadConfig(is); - } catch (FileNotFoundException e) { - logger.log(Level.SEVERE, "Default Properties file not found", e); - } - } - + * Loads configuration from an path which is a {@link Properties} file + * + * @param filePath Properties file path + */ + public void loadConfig(String filePath) { + try { + InputStream is = new FileInputStream(filePath); + loadConfig(is); + } catch (FileNotFoundException e) { + logger.log(Level.SEVERE, "Default Properties file not found", e); + } + } + /** * Returns the current configuration (default and user-defined) * * @return a {@link ConfigMap} containing key-value pairs of config entries */ - public ConfigMap getConfigContext() { - return configContext; - } - + public ConfigMap getConfigContext() { + return configContext; + } + } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java index f857b82..4dbae0c 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -309,12 +309,11 @@ public void loadInitializationParams(Properties props) { } private void loadInitializationParams() { - List configList = getConfigContext().getConfigList(); - - String mongoUri = getConfigValue(configList, DEFAULT_MONGODB_URI_PROP); + + String mongoUri = getConfigValue(DEFAULT_MONGODB_URI_PROP); if (mongoUri == null || mongoUri.isEmpty()) { - String mongoHost = getConfigValue(configList, DEFAULT_MONGODB_HOST_PROP); - String mongoPort = getConfigValue(configList, DEFAULT_MONGODB_PORT_PROP); + String mongoHost = getConfigValue(DEFAULT_MONGODB_HOST_PROP); + String mongoPort = getConfigValue(DEFAULT_MONGODB_PORT_PROP); int mongoPortInt = IntUtils.tryParseInt(mongoPort) == true ? Integer.valueOf(mongoPort) : -1; if (mongoHost != null && mongoPortInt != -1) { initMongoDbConnection(mongoHost, mongoPortInt); @@ -326,15 +325,15 @@ private void loadInitializationParams() { } String projectName = System.getProperty(DEFAULT_PROJECT_NAME_PROP); - projectName = projectName == null || projectName.isEmpty() ? getConfigValue(configList, DEFAULT_PROJECT_NAME_PROP) : projectName; + projectName = projectName == null || projectName.isEmpty() ? getConfigValue(DEFAULT_PROJECT_NAME_PROP) : projectName; this.projectName = projectName == null || projectName.isEmpty() ? this.projectName : projectName; String reportName = System.getProperty(DEFAULT_REPORT_NAME_PROP); - reportName = reportName == null || reportName.isEmpty() ? getConfigValue(configList, DEFAULT_REPORT_NAME_PROP) : reportName; + reportName = reportName == null || reportName.isEmpty() ? getConfigValue( DEFAULT_REPORT_NAME_PROP) : reportName; this.reportName = reportName == null || reportName.isEmpty() ? this.reportName : reportName; - String klovHost = getConfigValue(configList, DEFAULT_KLOV_HOST_PROP); - String klovPort = getConfigValue(configList, DEFAULT_KLOV_PORT_PROP); + String klovHost = getConfigValue(DEFAULT_KLOV_HOST_PROP); + String klovPort = getConfigValue(DEFAULT_KLOV_PORT_PROP); if (klovHost != null && klovPort != null) { String uri = klovHost + ":" + klovPort; @@ -344,14 +343,8 @@ private void loadInitializationParams() { } else { } } - private String getConfigValue(List configList, String key) { - Config c = configList.stream() - .filter(x -> x.getKey().equalsIgnoreCase(key)) - .findFirst() - .get(); - if (c != null) - return String.valueOf(c.getValue()); - return null; + private String getConfigValue(String key) { + return String.valueOf(configContext.getValue(key)); } @Override diff --git a/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java b/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java index ce023a3..888bb84 100644 --- a/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java +++ b/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java @@ -12,7 +12,7 @@ public class HtmlBasicFileReporterConfigurationTest extends Base { @Test public void htmlReporterHasInitialConfig(Method method) { ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - Assert.assertFalse(html.getConfigContext().getConfigList().isEmpty()); + Assert.assertFalse(html.getConfigContext().isEmpty()); } @Test diff --git a/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java b/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java index 2cdc865..8e7be1d 100644 --- a/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java +++ b/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java @@ -28,37 +28,38 @@ public void beforeClass() { } @Test - public void testTheme(Method method) { + public void testTheme() { Assert.assertEquals(html.getConfigContext().getValue("theme"), THEME); } @Test - public void testEncoding(Method method) { + public void testEncoding() { + html.getConfigContext().printMapForTest(); Assert.assertTrue(String.valueOf(html.getConfigContext().getValue("encoding")).equalsIgnoreCase(ENCODING)); } @Test - public void testDocumentTitle(Method method) { + public void testDocumentTitle() { Assert.assertEquals(html.getConfigContext().getValue("documentTitle"), DOCUMENT_TITLE); } @Test - public void testReportName(Method method) { + public void testReportName() { Assert.assertEquals(html.getConfigContext().getValue("reportName"), REPORT_NAME); } @Test - public void testTimestampFormat(Method method) { + public void testTimestampFormat() { Assert.assertEquals(html.getConfigContext().getValue("timeStampFormat"), TIMESTAMP_FORMAT); } @Test - public void testCSS(Method method) { + public void testCSS() { Assert.assertTrue(html.getConfigContext().getValue("styles").toString().contains(CSS)); } @Test - public void testJS(Method method) { + public void testJS() { Assert.assertTrue(html.getConfigContext().getValue("scripts").toString().contains(JS)); } diff --git a/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java b/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java index 83cafa6..8a9ec89 100644 --- a/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java +++ b/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java @@ -12,7 +12,7 @@ public class LoggerBasicFileReporterConfigurationTest2 extends Base { @Test public void htmlReporterHasInitialConfig(Method method) { ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - Assert.assertFalse(logger.getConfigContext().getConfigList().isEmpty()); + Assert.assertFalse(logger.getConfigContext().isEmpty()); } @Test From 8507f30ad7cfd6e9dec4b21407f4d66f5a53ff8b Mon Sep 17 00:00:00 2001 From: Virender Singh Date: Tue, 26 Feb 2019 21:56:55 +0530 Subject: [PATCH 09/77] Code style fixes and removing Config class --- .../externalconfig/ConfigLoader.java | 92 +- .../externalconfig/model/Config.java | 23 - .../externalconfig/model/ConfigMap.java | 27 +- .../reporter/BasicFileReporter.java | 445 +++--- .../reporter/ConfigurableReporter.java | 1 - .../reporter/ExtentKlovReporter.java | 1238 ++++++++--------- ...tmlBasicFileReporterConfigurationTest.java | 196 +-- .../HtmlConfigurableReporterTest.java | 107 +- ...erBasicFileReporterConfigurationTest2.java | 196 +-- 9 files changed, 1125 insertions(+), 1200 deletions(-) delete mode 100644 src/main/java/com/aventstack/extentreports/externalconfig/model/Config.java diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java b/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java index e8fbd84..4e47f9a 100644 --- a/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java +++ b/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java @@ -20,83 +20,75 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import com.aventstack.extentreports.externalconfig.model.Config; import com.aventstack.extentreports.externalconfig.model.ConfigMap; public class ConfigLoader { - - private static final Logger logger = Logger.getLogger(ConfigLoader.class.getName()); - + + private static final Logger logger = Logger.getLogger(ConfigLoader.class.getName()); + private ConfigMap configContext; private InputStream stream; ConfigLoader() { - configContext = new ConfigMap(); - } - - public ConfigLoader(URL url) { - this(); - - try { - stream = url.openStream(); - } - catch (IOException e) { - logger.log(Level.SEVERE, url.toString(), e); - } - } - - public ConfigLoader(File file, Boolean silent) { - this(); - - try { - if (silent && !file.exists()) - return; - stream = new FileInputStream(file); - } - catch (FileNotFoundException e) { - logger.log(Level.SEVERE, file.getPath(), e); - } - } - + configContext = new ConfigMap(); + } + + public ConfigLoader(URL url) { + this(); + + try { + stream = url.openStream(); + } catch (IOException e) { + logger.log(Level.SEVERE, url.toString(), e); + } + } + + public ConfigLoader(File file, Boolean silent) { + this(); + + try { + if (silent && !file.exists()) + return; + stream = new FileInputStream(file); + } catch (FileNotFoundException e) { + logger.log(Level.SEVERE, file.getPath(), e); + } + } + public ConfigMap getConfigurationHash() { if (stream == null) return null; - + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder; String value; - + try { dBuilder = dbFactory.newDocumentBuilder(); - + Document doc = dBuilder.parse(stream); doc.getDocumentElement().normalize(); - + NodeList nodeList = doc.getElementsByTagName("configuration").item(0).getChildNodes(); - + for (int ix = 0; ix < nodeList.getLength(); ix++) { Node node = nodeList.item(ix); - - Element el = node.getNodeType() == Node.ELEMENT_NODE - ? (Element) node - : null; + + Element el = node.getNodeType() == Node.ELEMENT_NODE ? (Element) node : null; if (el != null) { value = el.getTextContent(); - - value = el instanceof CharacterData - ? ((CharacterData) el).getData() - : value; - configContext.setConfig(el.getNodeName(), value); + + value = el instanceof CharacterData ? ((CharacterData) el).getData() : value; + configContext.setConfig(el.getNodeName(), value); } } - + return configContext; - } - catch (IOException|SAXException|ParserConfigurationException e) { - logger.log(Level.SEVERE, "Config", e); + } catch (IOException | SAXException | ParserConfigurationException e) { + logger.log(Level.SEVERE, "Config", e); } - + return null; } } diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/model/Config.java b/src/main/java/com/aventstack/extentreports/externalconfig/model/Config.java deleted file mode 100644 index e1d34dc..0000000 --- a/src/main/java/com/aventstack/extentreports/externalconfig/model/Config.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aventstack.extentreports.externalconfig.model; - -public class Config { - - private String k; - private Object v; - - public void setKey(String k) { - this.k = k; - } - - public String getKey() { - return k; - } - - public void setValue(Object v) { - this.v = v; - } - - public Object getValue() { - return v; - } -} diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java b/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java index 889013c..0f80409 100644 --- a/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java +++ b/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java @@ -15,10 +15,6 @@ public void setConfig(String key, Object value) { configMap.put(key, value); } - public Map getConfigMap() { - return configMap; - } - public boolean containsKey(String k) { return configMap.containsKey(k); } @@ -30,27 +26,20 @@ void removeKey(String k) { public Object getValue(String k) { return configMap.containsKey(k) ? configMap.get(k) : null; } - - public void appendConfig(Map configurations) - { - // This might create a hard dependency on Java 8. As Lambda function were introduced in Java *. + + public void appendConfig(Map configurations) { + // This might create a hard dependency on Java 8. As Lambda function were + // introduced in Java *. // We can instead have an in-line implementation of BiConsumer interface - configurations.forEach((key, value) -> this.setConfig(key, value)); + configurations.forEach((key, value) -> this.setConfig(key, value)); } - - public void appendConfig(ConfigMap configurations) - { + + public void appendConfig(ConfigMap configurations) { Map map = configurations.configMap; this.appendConfig(map); } - - + public boolean isEmpty() { return configMap.isEmpty(); } - - public void printMapForTest() - { - configMap.forEach((key, value) -> System.out.println("Key: " + key + " value: " + String.valueOf(value))); - } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index fa98ef2..10e387a 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -19,7 +19,6 @@ import com.aventstack.extentreports.Status; import com.aventstack.extentreports.SystemAttributeContext; import com.aventstack.extentreports.TestAttributeTestContextProvider; -import com.aventstack.extentreports.externalconfig.model.Config; import com.aventstack.extentreports.mediastorage.LocalMediaStorageHandler; import com.aventstack.extentreports.mediastorage.MediaStorage; import com.aventstack.extentreports.model.Author; @@ -49,271 +48,277 @@ * A base class for all reporter types that generate an output file * */ -public abstract class BasicFileReporter - extends AbstractReporter { +public abstract class BasicFileReporter extends AbstractReporter { private static final Logger logger = Logger.getLogger(BasicFileReporter.class.getName()); - + private static final String DEFAULT_MEDIA_SAVE_PROPERTY_NAME = "autoCreateRelativePathMedia"; private static final String TEMPLATE_LOCATION = "view/"; - + private static String encoding = "UTF-8"; - + private String source; - protected String filePath; - protected String destination; - protected Map templateMap; - - private BasicFileConfiguration userConfig; - private MediaStorage media; - private List testList; - private List testRunnerLogs; - private ExceptionTestContextImpl exceptionContext; - private TestAttributeTestContextProvider categoryContext; - private TestAttributeTestContextProvider authorContext; - private TestAttributeTestContextProvider deviceContext; - private SystemAttributeContext systemAttributeContext; - private ReportStatusStats stats; - private List statusList; - - protected BasicFileReporter(String path) { - this.filePath = path; - } - - protected BasicFileReporter(File path) { - this.filePath = path.getAbsolutePath(); - } - - protected void setFilePath(String filePath) { - this.filePath = filePath; - } - - public String getFilePath() { - return filePath; - } - - public File getFileFile() { - return new File(filePath); - } - - protected void init(String[] configFilePath, BasicFileConfiguration userConfig) { - this.userConfig = userConfig; - - // Required to parse the start and end times in the HTML report. - Locale.setDefault(Locale.ENGLISH); - loadDefaultConfig(configFilePath); - - File f = new File(getFilePath()); - File parentFile; - if (f.isDirectory() || FileUtil.getExtension(f).isEmpty()) { - parentFile = f; - } else { - parentFile = f.getParentFile(); - } - destination = parentFile == null ? "" : parentFile.getAbsolutePath() + "/"; - File destinationFile = new File(destination); - if (!destinationFile.exists()) { - destinationFile.mkdirs(); - } - } - - protected void loadUserConfig() { - for (Map.Entry entry : userConfig.getConfigMap().entrySet()) { - if (entry.getValue() != null) { - configContext.setConfig(entry.getKey().toString(), entry.getValue()); - } - } - } - - private void loadDefaultConfig(String[] configFilePath) { - ClassLoader loader = getClass().getClassLoader(); - Arrays.stream(configFilePath) - .map(x -> loader.getResourceAsStream(x)) - .filter(x -> x != null) - .findFirst() - .ifPresent(x -> loadConfig(x)); - } - - @Override - public void start() { - if (templateMap != null) { - return; - } - - templateMap = new HashMap<>(); - templateMap.put("report", this); - templateMap.put("MaterialIcon", new MaterialIcon()); - templateMap.put("Icon", new Icon()); - templateMap.put("TWBSColor", new TWBSColor()); - - BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_23); - BeansWrapper beansWrapper = builder.build(); - - try { - TemplateHashModel fieldTypeModel = (TemplateHashModel)beansWrapper.getEnumModels() - .get(Status.class.getName()); - templateMap.put("Status", fieldTypeModel); - } catch (TemplateModelException e) { - logger.log(Level.SEVERE, "", e); - } - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - super.flush(reportAggregates); - this.authorContext = reportAggregates.getAuthorContext(); - this.categoryContext = reportAggregates.getCategoryContext(); - this.deviceContext = reportAggregates.getDeviceContext(); - this.exceptionContext = reportAggregates.getExceptionContext(); - this.stats = reportAggregates.getReportStatusStats(); - this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); - this.testList = reportAggregates.getTestList(); - this.testRunnerLogs = reportAggregates.getTestRunnerLogs(); - this.statusList = reportAggregates.getStatusList(); - } - - public List getTestList() { + protected String filePath; + protected String destination; + protected Map templateMap; + + private BasicFileConfiguration userConfig; + private MediaStorage media; + private List testList; + private List testRunnerLogs; + private ExceptionTestContextImpl exceptionContext; + private TestAttributeTestContextProvider categoryContext; + private TestAttributeTestContextProvider authorContext; + private TestAttributeTestContextProvider deviceContext; + private SystemAttributeContext systemAttributeContext; + private ReportStatusStats stats; + private List statusList; + + protected BasicFileReporter(String path) { + this.filePath = path; + } + + protected BasicFileReporter(File path) { + this.filePath = path.getAbsolutePath(); + } + + protected void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFilePath() { + return filePath; + } + + public File getFileFile() { + return new File(filePath); + } + + protected void init(String[] configFilePath, BasicFileConfiguration userConfig) { + this.userConfig = userConfig; + + // Required to parse the start and end times in the HTML report. + Locale.setDefault(Locale.ENGLISH); + loadDefaultConfig(configFilePath); + + File f = new File(getFilePath()); + File parentFile; + if (f.isDirectory() || FileUtil.getExtension(f).isEmpty()) { + parentFile = f; + } else { + parentFile = f.getParentFile(); + } + destination = parentFile == null ? "" : parentFile.getAbsolutePath() + "/"; + File destinationFile = new File(destination); + if (!destinationFile.exists()) { + destinationFile.mkdirs(); + } + } + + protected void loadUserConfig() { + for (Map.Entry entry : userConfig.getConfigMap().entrySet()) { + if (entry.getValue() != null) { + configContext.setConfig(entry.getKey().toString(), entry.getValue()); + } + } + } + + private void loadDefaultConfig(String[] configFilePath) { + ClassLoader loader = getClass().getClassLoader(); + Arrays.stream(configFilePath).map(x -> loader.getResourceAsStream(x)).filter(x -> x != null).findFirst() + .ifPresent(x -> loadConfig(x)); + } + + @Override + public void start() { + if (templateMap != null) { + return; + } + + templateMap = new HashMap<>(); + templateMap.put("report", this); + templateMap.put("MaterialIcon", new MaterialIcon()); + templateMap.put("Icon", new Icon()); + templateMap.put("TWBSColor", new TWBSColor()); + + BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_23); + BeansWrapper beansWrapper = builder.build(); + + try { + TemplateHashModel fieldTypeModel = (TemplateHashModel) beansWrapper.getEnumModels() + .get(Status.class.getName()); + templateMap.put("Status", fieldTypeModel); + } catch (TemplateModelException e) { + logger.log(Level.SEVERE, "", e); + } + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + super.flush(reportAggregates); + this.authorContext = reportAggregates.getAuthorContext(); + this.categoryContext = reportAggregates.getCategoryContext(); + this.deviceContext = reportAggregates.getDeviceContext(); + this.exceptionContext = reportAggregates.getExceptionContext(); + this.stats = reportAggregates.getReportStatusStats(); + this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); + this.testList = reportAggregates.getTestList(); + this.testRunnerLogs = reportAggregates.getTestRunnerLogs(); + this.statusList = reportAggregates.getStatusList(); + } + + public List getTestList() { return testList; } - public List getTestRunnerLogs() { - return testRunnerLogs; - } + public List getTestRunnerLogs() { + return testRunnerLogs; + } + + public TestAttributeTestContextProvider getCategoryContextInfo() { + return categoryContext; + } - public TestAttributeTestContextProvider getCategoryContextInfo() { - return categoryContext; - } - public TestAttributeTestContextProvider getAuthorContextInfo() { - return authorContext; - } - + return authorContext; + } + public TestAttributeTestContextProvider getDeviceContextInfo() { return deviceContext; } - - public ExceptionTestContextImpl getExceptionContextInfo() { - return exceptionContext; - } - public SystemAttributeContext getSystemAttributeContext() { - return systemAttributeContext; - } + public ExceptionTestContextImpl getExceptionContextInfo() { + return exceptionContext; + } + + public SystemAttributeContext getSystemAttributeContext() { + return systemAttributeContext; + } public ReportStatusStats getReportStatusStats() { - return stats; - } - + return stats; + } + @Override public List getStatusList() { return statusList; } - + + @Override + public void onTestStarted(Test test) { + } + @Override - public void onTestStarted(Test test) { } + public void onTestRemoved(Test test) { + } @Override - public void onTestRemoved(Test test) { } + public void onNodeStarted(Test node) { + } @Override - public void onNodeStarted(Test node) { } + public void onLogAdded(Test test, Log log) { + } @Override - public void onLogAdded(Test test, Log log) { } + public void onCategoryAssigned(Test test, Category category) { + } @Override - public void onCategoryAssigned(Test test, Category category) { } + public void onAuthorAssigned(Test test, Author author) { + } @Override - public void onAuthorAssigned(Test test, Author author) { } + public void onDeviceAssigned(Test test, Device device) { + } @Override - public void onDeviceAssigned(Test test, Device device) { } - + public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { + mediaExists(screenCapture); + autoCreateRelativePathMedia(screenCapture); + } + @Override - public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { + public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { mediaExists(screenCapture); - autoCreateRelativePathMedia(screenCapture); - } - - @Override - public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { - mediaExists(screenCapture); - autoCreateRelativePathMedia(screenCapture); - } - - private void mediaExists(Media m) { - if (m.getPath() != null && !new File(m.getPath()).exists()) { } - } - - private void autoCreateRelativePathMedia(ScreenCapture screenCapture) throws IOException { - // if user has not specific a configuration, exit - if (userConfig == null || screenCapture.isBase64()) - return; - - String autoCreateRelativePathMedia = userConfig.getConfigMap().get(DEFAULT_MEDIA_SAVE_PROPERTY_NAME); - // check always so user has the option to disable this setting at anytime - if (autoCreateRelativePathMedia != null && Boolean.valueOf(autoCreateRelativePathMedia)) { - if (media == null) { - media = new LocalMediaStorageHandler(); - media.init(destination); - } - media.storeMedia(screenCapture); - } - } - - @Override - public void stop() { } - - @Override - public Date getStartTime() { - return super.getStartTime(); - } - - @Override - public Date getEndTime() { - return super.getEndTime(); - } + autoCreateRelativePathMedia(screenCapture); + } + + private void mediaExists(Media m) { + if (m.getPath() != null && !new File(m.getPath()).exists()) { + } + } + + private void autoCreateRelativePathMedia(ScreenCapture screenCapture) throws IOException { + // if user has not specific a configuration, exit + if (userConfig == null || screenCapture.isBase64()) + return; + + String autoCreateRelativePathMedia = userConfig.getConfigMap().get(DEFAULT_MEDIA_SAVE_PROPERTY_NAME); + // check always so user has the option to disable this setting at anytime + if (autoCreateRelativePathMedia != null && Boolean.valueOf(autoCreateRelativePathMedia)) { + if (media == null) { + media = new LocalMediaStorageHandler(); + media.init(destination); + } + media.storeMedia(screenCapture); + } + } @Override - public void onScreencastAdded(Test test, Screencast screencast) throws IOException { } - + public void stop() { + } + + @Override + public Date getStartTime() { + return super.getStartTime(); + } + + @Override + public Date getEndTime() { + return super.getEndTime(); + } + + @Override + public void onScreencastAdded(Test test, Screencast screencast) throws IOException { + } + public boolean containsStatus(String status) { Status s = Status.valueOf(status.toUpperCase()); return containsStatus(s); } - + public boolean containsStatus(Status status) { - return getStatusList() != null && !getStatusList().isEmpty() && getStatusList().contains(status); - } - + return getStatusList() != null && !getStatusList().isEmpty() && getStatusList().contains(status); + } + protected void processTemplate(Template template, File outputFile) throws TemplateException, IOException { - StringWriter out = new StringWriter(); - template.process(templateMap, out); - source = out.toString(); - Writer.getInstance().write(outputFile, source); - out.close(); - } - - protected String getSource() { + StringWriter out = new StringWriter(); + template.process(templateMap, out); + source = out.toString(); + Writer.getInstance().write(outputFile, source); + out.close(); + } + + protected String getSource() { return source; } - + protected Configuration getFreemarkerConfig() { - Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); - cfg.setClassForTemplateLoading(ExtentReports.class, TEMPLATE_LOCATION); - cfg.setDefaultEncoding(encoding); - return cfg; - } - - protected Boolean enforceOfflineMode() { - if (configContext.containsKey("enableOfflineMode")) { - String offlineMode = String.valueOf(configContext.getValue("enableOfflineMode")); - if (!configContext.containsKey("offlineDirectory") && offlineMode.equals("true")) { - return true; - } - } - return false; - } + Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); + cfg.setClassForTemplateLoading(ExtentReports.class, TEMPLATE_LOCATION); + cfg.setDefaultEncoding(encoding); + return cfg; + } + + protected Boolean enforceOfflineMode() { + if (configContext.containsKey("enableOfflineMode")) { + String offlineMode = String.valueOf(configContext.getValue("enableOfflineMode")); + if (!configContext.containsKey("offlineDirectory") && offlineMode.equals("true")) { + return true; + } + } + return false; + } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java index 13a114b..11ad6b7 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java @@ -11,7 +11,6 @@ import com.aventstack.extentreports.ExtentReporter; import com.aventstack.extentreports.externalconfig.ConfigLoader; -import com.aventstack.extentreports.externalconfig.model.Config; import com.aventstack.extentreports.externalconfig.model.ConfigMap; /** diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java index 4dbae0c..fd30efc 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -22,7 +22,6 @@ import com.aventstack.extentreports.Status; import com.aventstack.extentreports.SystemAttributeContext; import com.aventstack.extentreports.TestAttributeTestContextProvider; -import com.aventstack.extentreports.externalconfig.model.Config; import com.aventstack.extentreports.mediastorage.KlovMediaStorageHandler; import com.aventstack.extentreports.mediastorage.model.KlovMedia; import com.aventstack.extentreports.model.Author; @@ -48,11 +47,11 @@ import com.mongodb.client.MongoDatabase; /** - * ExtentKlovReporter is a NoSQL database reporter (MongoDB), which updates information in - * the database which is then used by the ExtentX server to display in-depth analysis. + * ExtentKlovReporter is a NoSQL database reporter (MongoDB), which updates + * information in the database which is then used by the ExtentX server to + * display in-depth analysis. */ -public class ExtentKlovReporter - extends AbstractReporter { +public class ExtentKlovReporter extends AbstractReporter { private static final String DEFAULT_PROJECT_NAME_PROP = "klov.project.name"; private static final String DEFAULT_REPORT_NAME_PROP = "klov.report.name"; @@ -63,276 +62,280 @@ public class ExtentKlovReporter private static final String DEFAULT_KLOV_PORT_PROP = "klov.port"; private static final String REPORTER_NAME = "klov"; private static final String DB_NAME = "klov"; - private static final String DEFAULT_PROJECT_NAME = "Default"; - - private String url; - - private List testList; - private ReportStatusStats stats; - private SystemAttributeContext systemAttributeContext; - private TestAttributeTestContextProvider categoryContext; - private TestAttributeTestContextProvider authorContext; - private TestAttributeTestContextProvider deviceContext; - private Map categoryNameObjectIdCollection = new HashMap<>(); - private Map authorNameObjectIdCollection = new HashMap<>(); - private Map deviceNameObjectIdCollection = new HashMap<>(); - private Map exceptionNameObjectIdCollection = new HashMap<>(); - - private ObjectId reportId; - private String reportName; - private ObjectId projectId; - private String projectName; - - private MongoClient mongoClient; - - private MongoCollection projectCollection; - private MongoCollection reportCollection; - private MongoCollection testCollection; - private MongoCollection logCollection; - private MongoCollection exceptionCollection; - private MongoCollection mediaCollection; - private MongoCollection categoryCollection; - private MongoCollection authorCollection; - private MongoCollection deviceCollection; - private MongoCollection environmentCollection; - - static { - /* use mongodb reporting for only critical/severe events */ - Logger mongoLogger = Logger.getLogger("org.mongodb.driver"); - mongoLogger.setLevel(Level.SEVERE); - } - - /** - * Initializes the KlovReporter - */ - public ExtentKlovReporter() { } - - /** - * Initializes the KlovReporter with project and report names - * - * @param projectName Name of the project - * @param reportName Name of the report - */ - public ExtentKlovReporter(String projectName, String reportName) { - this.projectName = projectName; - this.reportName = reportName; - } - - /** - * Sets the project name - * - * @param projectName Name of the project - */ - public void setProjectName(String projectName) { - this.projectName = projectName; - } - - /** - * Sets the report name - * - * @param reportName Name of the report - */ - public void setReportName(String reportName) { - this.reportName = reportName; - } - - /** - * Initialize Mongo DB connection with host and default port: 27017 - * - * @param host host name - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(String host) { - mongoClient = new MongoClient(host, 27017); - return this; - } - - /** - * Initialize Mongo DB connection with host and {@link MongoClientOptions} - * - * @param host host name - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(String host, MongoClientOptions options) { - mongoClient = new MongoClient(host, options); - return this; - } - - /** - * Initialize Mongo DB connection with host and post - * - * @param host host name - * @param port port number - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(String host, int port) { - mongoClient = new MongoClient(host, port); - return this; - } - - /** - * Initialize Mongo DB connection with a {@link MongoClientURI} - * - * @param uri {@link MongoClientURI} uri - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(MongoClientURI uri) { - mongoClient = new MongoClient(uri); - return this; - } - - /** - * Initializes the Mongo DB connection with {@link ServerAddress} - * - * @param addr {@link ServerAddress} server address - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr) { - mongoClient = new MongoClient(addr); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} - * addresses - * - * @param seeds A list of {@link ServerAddress} server addresses - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds) { - mongoClient = new MongoClient(seeds); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} - * and {@link MongoCredential} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList) { - mongoClient = new MongoClient(seeds, credentialsList); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress}, - * {@link MongoCredential} and {@link MongoClientOptions} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList, MongoClientOptions options) { - mongoClient = new MongoClient(seeds, credentialsList, options); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} - * and {@link MongoClientOptions} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, MongoClientOptions options) { - mongoClient = new MongoClient(seeds, options); - return this; - } - - /** - * Initializes the Mongo DB connection with {@link ServerAddress} and a list of - * {@link MongoCredential} credentials - * - * @param addr {@link ServerAddress} server address - * @param credentialsList A list of {@link MongoCredential} credentials - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList) { - mongoClient = new MongoClient(addr, credentialsList); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress}, - * {@link MongoCredential} and {@link MongoClientOptions} - * - * @param addr A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList, MongoClientOptions options) { - mongoClient = new MongoClient(addr, credentialsList, options); - return this; - } - - /** - * Initializes the Mongo DB connection with a {@link ServerAddress} and - * {@link MongoClientOptions} - * - * @param addr A list of {@link ServerAddress} server addresses - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, MongoClientOptions options) { - mongoClient = new MongoClient(addr, options); - return this; - } - - /** - * Initializes the Mongo DB connection with a connection url - * - * @param url Url string - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initKlovServerConnection(String url) { - this.url = url; - return this; - } - - public void loadInitializationParams(String propertiesPath) throws FileNotFoundException { - File f = new File(propertiesPath); - InputStream stream = new FileInputStream(f); - loadConfig(stream); - loadInitializationParams(); - } - - public void loadInitializationParams(Properties props) { - loadConfig(props); - loadInitializationParams(); - } - - private void loadInitializationParams() { - - String mongoUri = getConfigValue(DEFAULT_MONGODB_URI_PROP); - if (mongoUri == null || mongoUri.isEmpty()) { - String mongoHost = getConfigValue(DEFAULT_MONGODB_HOST_PROP); - String mongoPort = getConfigValue(DEFAULT_MONGODB_PORT_PROP); - int mongoPortInt = IntUtils.tryParseInt(mongoPort) == true ? Integer.valueOf(mongoPort) : -1; - if (mongoHost != null && mongoPortInt != -1) { - initMongoDbConnection(mongoHost, mongoPortInt); - } else if (mongoHost != null) { - initMongoDbConnection(mongoHost); - } - } else { - initMongoDbConnection(new MongoClientURI(mongoUri)); - } - - String projectName = System.getProperty(DEFAULT_PROJECT_NAME_PROP); - projectName = projectName == null || projectName.isEmpty() ? getConfigValue(DEFAULT_PROJECT_NAME_PROP) : projectName; - this.projectName = projectName == null || projectName.isEmpty() ? this.projectName : projectName; - - String reportName = System.getProperty(DEFAULT_REPORT_NAME_PROP); - reportName = reportName == null || reportName.isEmpty() ? getConfigValue( DEFAULT_REPORT_NAME_PROP) : reportName; - this.reportName = reportName == null || reportName.isEmpty() ? this.reportName : reportName; - - String klovHost = getConfigValue(DEFAULT_KLOV_HOST_PROP); + private static final String DEFAULT_PROJECT_NAME = "Default"; + + private String url; + + private List testList; + private ReportStatusStats stats; + private SystemAttributeContext systemAttributeContext; + private TestAttributeTestContextProvider categoryContext; + private TestAttributeTestContextProvider authorContext; + private TestAttributeTestContextProvider deviceContext; + private Map categoryNameObjectIdCollection = new HashMap<>(); + private Map authorNameObjectIdCollection = new HashMap<>(); + private Map deviceNameObjectIdCollection = new HashMap<>(); + private Map exceptionNameObjectIdCollection = new HashMap<>(); + + private ObjectId reportId; + private String reportName; + private ObjectId projectId; + private String projectName; + + private MongoClient mongoClient; + + private MongoCollection projectCollection; + private MongoCollection reportCollection; + private MongoCollection testCollection; + private MongoCollection logCollection; + private MongoCollection exceptionCollection; + private MongoCollection mediaCollection; + private MongoCollection categoryCollection; + private MongoCollection authorCollection; + private MongoCollection deviceCollection; + private MongoCollection environmentCollection; + + static { + /* use mongodb reporting for only critical/severe events */ + Logger mongoLogger = Logger.getLogger("org.mongodb.driver"); + mongoLogger.setLevel(Level.SEVERE); + } + + /** + * Initializes the KlovReporter + */ + public ExtentKlovReporter() { + } + + /** + * Initializes the KlovReporter with project and report names + * + * @param projectName Name of the project + * @param reportName Name of the report + */ + public ExtentKlovReporter(String projectName, String reportName) { + this.projectName = projectName; + this.reportName = reportName; + } + + /** + * Sets the project name + * + * @param projectName Name of the project + */ + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + /** + * Sets the report name + * + * @param reportName Name of the report + */ + public void setReportName(String reportName) { + this.reportName = reportName; + } + + /** + * Initialize Mongo DB connection with host and default port: 27017 + * + * @param host host name + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(String host) { + mongoClient = new MongoClient(host, 27017); + return this; + } + + /** + * Initialize Mongo DB connection with host and {@link MongoClientOptions} + * + * @param host host name + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(String host, MongoClientOptions options) { + mongoClient = new MongoClient(host, options); + return this; + } + + /** + * Initialize Mongo DB connection with host and post + * + * @param host host name + * @param port port number + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(String host, int port) { + mongoClient = new MongoClient(host, port); + return this; + } + + /** + * Initialize Mongo DB connection with a {@link MongoClientURI} + * + * @param uri {@link MongoClientURI} uri + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(MongoClientURI uri) { + mongoClient = new MongoClient(uri); + return this; + } + + /** + * Initializes the Mongo DB connection with {@link ServerAddress} + * + * @param addr {@link ServerAddress} server address + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr) { + mongoClient = new MongoClient(addr); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress} + * addresses + * + * @param seeds A list of {@link ServerAddress} server addresses + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds) { + mongoClient = new MongoClient(seeds); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress} and + * {@link MongoCredential} + * + * @param seeds A list of {@link ServerAddress} server addresses + * @param credentialsList A list of {@link MongoCredential} credentials + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList) { + mongoClient = new MongoClient(seeds, credentialsList); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress}, + * {@link MongoCredential} and {@link MongoClientOptions} + * + * @param seeds A list of {@link ServerAddress} server addresses + * @param credentialsList A list of {@link MongoCredential} credentials + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList, + MongoClientOptions options) { + mongoClient = new MongoClient(seeds, credentialsList, options); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress} and + * {@link MongoClientOptions} + * + * @param seeds A list of {@link ServerAddress} server addresses + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds, MongoClientOptions options) { + mongoClient = new MongoClient(seeds, options); + return this; + } + + /** + * Initializes the Mongo DB connection with {@link ServerAddress} and a list of + * {@link MongoCredential} credentials + * + * @param addr {@link ServerAddress} server address + * @param credentialsList A list of {@link MongoCredential} credentials + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList) { + mongoClient = new MongoClient(addr, credentialsList); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress}, + * {@link MongoCredential} and {@link MongoClientOptions} + * + * @param addr A list of {@link ServerAddress} server addresses + * @param credentialsList A list of {@link MongoCredential} credentials + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList, + MongoClientOptions options) { + mongoClient = new MongoClient(addr, credentialsList, options); + return this; + } + + /** + * Initializes the Mongo DB connection with a {@link ServerAddress} and + * {@link MongoClientOptions} + * + * @param addr A list of {@link ServerAddress} server addresses + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, MongoClientOptions options) { + mongoClient = new MongoClient(addr, options); + return this; + } + + /** + * Initializes the Mongo DB connection with a connection url + * + * @param url Url string + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initKlovServerConnection(String url) { + this.url = url; + return this; + } + + public void loadInitializationParams(String propertiesPath) throws FileNotFoundException { + File f = new File(propertiesPath); + InputStream stream = new FileInputStream(f); + loadConfig(stream); + loadInitializationParams(); + } + + public void loadInitializationParams(Properties props) { + loadConfig(props); + loadInitializationParams(); + } + + private void loadInitializationParams() { + + String mongoUri = getConfigValue(DEFAULT_MONGODB_URI_PROP); + if (mongoUri == null || mongoUri.isEmpty()) { + String mongoHost = getConfigValue(DEFAULT_MONGODB_HOST_PROP); + String mongoPort = getConfigValue(DEFAULT_MONGODB_PORT_PROP); + int mongoPortInt = IntUtils.tryParseInt(mongoPort) == true ? Integer.valueOf(mongoPort) : -1; + if (mongoHost != null && mongoPortInt != -1) { + initMongoDbConnection(mongoHost, mongoPortInt); + } else if (mongoHost != null) { + initMongoDbConnection(mongoHost); + } + } else { + initMongoDbConnection(new MongoClientURI(mongoUri)); + } + + String projectName = System.getProperty(DEFAULT_PROJECT_NAME_PROP); + projectName = projectName == null || projectName.isEmpty() ? getConfigValue(DEFAULT_PROJECT_NAME_PROP) + : projectName; + this.projectName = projectName == null || projectName.isEmpty() ? this.projectName : projectName; + + String reportName = System.getProperty(DEFAULT_REPORT_NAME_PROP); + reportName = reportName == null || reportName.isEmpty() ? getConfigValue(DEFAULT_REPORT_NAME_PROP) : reportName; + this.reportName = reportName == null || reportName.isEmpty() ? this.reportName : reportName; + + String klovHost = getConfigValue(DEFAULT_KLOV_HOST_PROP); String klovPort = getConfigValue(DEFAULT_KLOV_PORT_PROP); if (klovHost != null && klovPort != null) { @@ -340,370 +343,331 @@ private void loadInitializationParams() { initKlovServerConnection(uri); } else if (klovHost != null) { initKlovServerConnection(klovHost); - } else { } - } - - private String getConfigValue(String key) { - return String.valueOf(configContext.getValue(key)); - } - - @Override - public void start() { - MongoDatabase db = mongoClient.getDatabase(DB_NAME); - initCollections(db); - setupProject(); - } - - private void initCollections(MongoDatabase db) { - projectCollection = db.getCollection("project"); - reportCollection = db.getCollection("report"); - testCollection = db.getCollection("test"); - logCollection = db.getCollection("log"); - exceptionCollection = db.getCollection("exception"); - mediaCollection = db.getCollection("media"); - categoryCollection = db.getCollection("category"); - authorCollection = db.getCollection("author"); - deviceCollection = db.getCollection("device"); - environmentCollection = db.getCollection("environment"); - } - - private void setupProject() { - String projectName = this.projectName == null || this.projectName.isEmpty() - ? DEFAULT_PROJECT_NAME - : this.projectName; - - Document doc = new Document("name", projectName); - Document project = projectCollection.find(doc).first(); - - if (project != null) { - projectId = project.getObjectId("_id"); - } - else { - doc.append("createdAt", Calendar.getInstance().getTime()); - projectCollection.insertOne(doc); - projectId = MongoUtil.getId(doc); - } - - setupReport(projectName); - } - - private void setupReport(String projectName) { - String reportName = - this.reportName == null || this.reportName.isEmpty() - ? "Build " + Calendar.getInstance().getTimeInMillis() - : this.reportName; - - Document doc = new Document("name", reportName) - .append("startTime", getStartTime()) - .append("project", projectId) - .append("projectName", projectName); - - reportCollection.insertOne(doc); - reportId = MongoUtil.getId(doc); - } - - @Override - public void stop() { - mongoClient.close(); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - setEndTime(Calendar.getInstance().getTime()); - this.testList = reportAggregates.getTestList(); - - if (testList == null || testList.isEmpty()) { - return; - } - - this.authorContext = reportAggregates.getAuthorContext(); - this.categoryContext = reportAggregates.getCategoryContext(); - this.deviceContext = reportAggregates.getDeviceContext(); - this.stats = reportAggregates.getReportStatusStats(); - this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); - - Status buildStatus = reportAggregates.getStatus(); - - Document doc = new Document("endTime", getEndTime()) - .append("duration", getRunDuration()) - .append("status", String.valueOf(buildStatus)) - .append("parentLength", stats.getParentCount()) - .append("passParentLength", stats.getParentCountPass()) - .append("failParentLength", stats.getParentCountFail()) - .append("fatalParentLength", stats.getParentCountFatal()) - .append("errorParentLength", stats.getParentCountError()) - .append("warningParentLength", stats.getParentCountWarning()) - .append("skipParentLength", stats.getParentCountSkip()) - .append("exceptionsParentLength", stats.getParentCountExceptions()) - .append("childLength", stats.getChildCount()) - .append("passChildLength", stats.getChildCountPass()) - .append("failChildLength", stats.getChildCountFail()) - .append("fatalChildLength", stats.getChildCountFatal()) - .append("errorChildLength", stats.getChildCountError()) - .append("warningChildLength", stats.getChildCountWarning()) - .append("skipChildLength", stats.getChildCountSkip()) - .append("infoChildLength", stats.getChildCountInfo()) - .append("exceptionsChildLength", stats.getChildCountExceptions()) - .append("grandChildLength", stats.getGrandChildCount()) - .append("passGrandChildLength", stats.getGrandChildCountPass()) - .append("failGrandChildLength", stats.getGrandChildCountFail()) - .append("fatalGrandChildLength", stats.getGrandChildCountFatal()) - .append("errorGrandChildLength", stats.getGrandChildCountError()) - .append("warningGrandChildLength", stats.getGrandChildCountWarning()) - .append("skipGrandChildLength", stats.getGrandChildCountSkip()) - .append("exceptionsGrandChildLength", stats.getGrandChildCountExceptions()) - .append("analysisStrategy", String.valueOf(getAnalysisStrategy())); - - reportCollection.updateOne( - new Document("_id", reportId), - new Document("$set", doc)); - - insertUpdateSystemAttribute(); - } - - public List getCollectionValues(Map collection) { - if (collection == null || collection.isEmpty()) - return null; - return collection.entrySet() - .stream() - .map(Map.Entry::getValue) - .collect(Collectors.toList()); - } - - private void insertUpdateSystemAttribute() { - List systemAttrList = systemAttributeContext.getSystemAttributeList(); - Document doc; - - for (SystemAttribute attr : systemAttrList) { - doc = new Document("project", projectId) - .append("report", reportId) - .append("name", attr.getName()); - - Document envSingle = environmentCollection.find(doc).first(); - - if (envSingle == null) { - doc.append("value", attr.getValue()); - environmentCollection.insertOne(doc); - } else { - ObjectId id = envSingle.getObjectId("_id"); - doc = new Document("_id", id) - .append("value", attr.getValue()); - environmentCollection.updateOne( - new Document("_id", id), - new Document("$set", doc)); - } - } - } - - @Override - public void onTestStarted(Test test) { - onTestStartedHelper(test); - } - - @Override - public synchronized void onNodeStarted(Test node) { - onTestStartedHelper(node); - } - - private void onTestStartedHelper(Test test) { - Document doc = new Document("project", projectId) - .append("report", reportId) - .append("reportName", reportName) - .append("level", test.getLevel()) - .append("name", test.getName()) - .append("status", test.getStatus().toString()) - .append("description", test.getDescription()) - .append("startTime", test.getStartTime()) - .append("endTime", test.getEndTime()) - .append("bdd", test.isBehaviorDrivenType()) - .append("leaf", test.getNodeContext().size()==0) - .append("childNodesLength", test.getNodeContext().size()); - - if (test.isBehaviorDrivenType()) { - doc.append("bddType", test.getBehaviorDrivenType().getSimpleName()); - } - - if (test.getParent() != null) { - doc.append("parent", test.getParent().getObjectId()) - .append("parentName", test.getParent().getName()); - updateTestChildrenCount(test.getParent()); - updateTestDesc(test.getParent()); - } - - testCollection.insertOne(doc); - ObjectId testId = MongoUtil.getId(doc); - test.setObjectId(testId); - } - - private void updateTestDesc(Test test) { - Document doc = new Document("description", test.getDescription()); - testCollection.updateOne( - new Document("_id", test.getObjectId()), - new Document("$set", doc)); - } - - private void updateTestChildrenCount(Test test) { - Document doc = new Document("childNodesLength", test.getNodeContext().size()); - testCollection.updateOne( - new Document("_id", test.getObjectId()), - new Document("$set", doc)); - } - - @Override - public synchronized void onLogAdded(Test test, Log log) { - Document doc = new Document("test", test.getObjectId()) - .append("project", projectId) - .append("report", reportId) - .append("testName", test.getName()) - .append("sequence", log.getSequence()) - .append("status", log.getStatus().toString()) - .append("timestamp", log.getTimestamp()) - .append("details", log.getDetails()); - - if (log.getExceptionInfo() != null) { - doc.append("exception", log.getExceptionInfo().getExceptionName()) - .append("stacktrace", log.getExceptionInfo().getStackTrace()); - } - + } else { + } + } + + private String getConfigValue(String key) { + return String.valueOf(configContext.getValue(key)); + } + + @Override + public void start() { + MongoDatabase db = mongoClient.getDatabase(DB_NAME); + initCollections(db); + setupProject(); + } + + private void initCollections(MongoDatabase db) { + projectCollection = db.getCollection("project"); + reportCollection = db.getCollection("report"); + testCollection = db.getCollection("test"); + logCollection = db.getCollection("log"); + exceptionCollection = db.getCollection("exception"); + mediaCollection = db.getCollection("media"); + categoryCollection = db.getCollection("category"); + authorCollection = db.getCollection("author"); + deviceCollection = db.getCollection("device"); + environmentCollection = db.getCollection("environment"); + } + + private void setupProject() { + String projectName = this.projectName == null || this.projectName.isEmpty() ? DEFAULT_PROJECT_NAME + : this.projectName; + + Document doc = new Document("name", projectName); + Document project = projectCollection.find(doc).first(); + + if (project != null) { + projectId = project.getObjectId("_id"); + } else { + doc.append("createdAt", Calendar.getInstance().getTime()); + projectCollection.insertOne(doc); + projectId = MongoUtil.getId(doc); + } + + setupReport(projectName); + } + + private void setupReport(String projectName) { + String reportName = this.reportName == null || this.reportName.isEmpty() + ? "Build " + Calendar.getInstance().getTimeInMillis() + : this.reportName; + + Document doc = new Document("name", reportName).append("startTime", getStartTime()).append("project", projectId) + .append("projectName", projectName); + + reportCollection.insertOne(doc); + reportId = MongoUtil.getId(doc); + } + + @Override + public void stop() { + mongoClient.close(); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + setEndTime(Calendar.getInstance().getTime()); + this.testList = reportAggregates.getTestList(); + + if (testList == null || testList.isEmpty()) { + return; + } + + this.authorContext = reportAggregates.getAuthorContext(); + this.categoryContext = reportAggregates.getCategoryContext(); + this.deviceContext = reportAggregates.getDeviceContext(); + this.stats = reportAggregates.getReportStatusStats(); + this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); + + Status buildStatus = reportAggregates.getStatus(); + + Document doc = new Document("endTime", getEndTime()).append("duration", getRunDuration()) + .append("status", String.valueOf(buildStatus)).append("parentLength", stats.getParentCount()) + .append("passParentLength", stats.getParentCountPass()) + .append("failParentLength", stats.getParentCountFail()) + .append("fatalParentLength", stats.getParentCountFatal()) + .append("errorParentLength", stats.getParentCountError()) + .append("warningParentLength", stats.getParentCountWarning()) + .append("skipParentLength", stats.getParentCountSkip()) + .append("exceptionsParentLength", stats.getParentCountExceptions()) + .append("childLength", stats.getChildCount()).append("passChildLength", stats.getChildCountPass()) + .append("failChildLength", stats.getChildCountFail()) + .append("fatalChildLength", stats.getChildCountFatal()) + .append("errorChildLength", stats.getChildCountError()) + .append("warningChildLength", stats.getChildCountWarning()) + .append("skipChildLength", stats.getChildCountSkip()) + .append("infoChildLength", stats.getChildCountInfo()) + .append("exceptionsChildLength", stats.getChildCountExceptions()) + .append("grandChildLength", stats.getGrandChildCount()) + .append("passGrandChildLength", stats.getGrandChildCountPass()) + .append("failGrandChildLength", stats.getGrandChildCountFail()) + .append("fatalGrandChildLength", stats.getGrandChildCountFatal()) + .append("errorGrandChildLength", stats.getGrandChildCountError()) + .append("warningGrandChildLength", stats.getGrandChildCountWarning()) + .append("skipGrandChildLength", stats.getGrandChildCountSkip()) + .append("exceptionsGrandChildLength", stats.getGrandChildCountExceptions()) + .append("analysisStrategy", String.valueOf(getAnalysisStrategy())); + + reportCollection.updateOne(new Document("_id", reportId), new Document("$set", doc)); + + insertUpdateSystemAttribute(); + } + + public List getCollectionValues(Map collection) { + if (collection == null || collection.isEmpty()) + return null; + return collection.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList()); + } + + private void insertUpdateSystemAttribute() { + List systemAttrList = systemAttributeContext.getSystemAttributeList(); + Document doc; + + for (SystemAttribute attr : systemAttrList) { + doc = new Document("project", projectId).append("report", reportId).append("name", attr.getName()); + + Document envSingle = environmentCollection.find(doc).first(); + + if (envSingle == null) { + doc.append("value", attr.getValue()); + environmentCollection.insertOne(doc); + } else { + ObjectId id = envSingle.getObjectId("_id"); + doc = new Document("_id", id).append("value", attr.getValue()); + environmentCollection.updateOne(new Document("_id", id), new Document("$set", doc)); + } + } + } + + @Override + public void onTestStarted(Test test) { + onTestStartedHelper(test); + } + + @Override + public synchronized void onNodeStarted(Test node) { + onTestStartedHelper(node); + } + + private void onTestStartedHelper(Test test) { + Document doc = new Document("project", projectId).append("report", reportId).append("reportName", reportName) + .append("level", test.getLevel()).append("name", test.getName()) + .append("status", test.getStatus().toString()).append("description", test.getDescription()) + .append("startTime", test.getStartTime()).append("endTime", test.getEndTime()) + .append("bdd", test.isBehaviorDrivenType()).append("leaf", test.getNodeContext().size() == 0) + .append("childNodesLength", test.getNodeContext().size()); + + if (test.isBehaviorDrivenType()) { + doc.append("bddType", test.getBehaviorDrivenType().getSimpleName()); + } + + if (test.getParent() != null) { + doc.append("parent", test.getParent().getObjectId()).append("parentName", test.getParent().getName()); + updateTestChildrenCount(test.getParent()); + updateTestDesc(test.getParent()); + } + + testCollection.insertOne(doc); + ObjectId testId = MongoUtil.getId(doc); + test.setObjectId(testId); + } + + private void updateTestDesc(Test test) { + Document doc = new Document("description", test.getDescription()); + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + } + + private void updateTestChildrenCount(Test test) { + Document doc = new Document("childNodesLength", test.getNodeContext().size()); + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + } + + @Override + public synchronized void onLogAdded(Test test, Log log) { + Document doc = new Document("test", test.getObjectId()).append("project", projectId).append("report", reportId) + .append("testName", test.getName()).append("sequence", log.getSequence()) + .append("status", log.getStatus().toString()).append("timestamp", log.getTimestamp()) + .append("details", log.getDetails()); + + if (log.getExceptionInfo() != null) { + doc.append("exception", log.getExceptionInfo().getExceptionName()).append("stacktrace", + log.getExceptionInfo().getStackTrace()); + } + if (log.hasScreenCapture() && log.getScreenCaptureContext().getFirst().isBase64()) { - doc.append("details", log.getDetails() + log.getScreenCaptureContext().getFirst().getSource()); - } - - logCollection.insertOne(doc); - - ObjectId logId = MongoUtil.getId(doc); - log.setObjectId(logId); - - // check for exceptions.. - if (test.hasException()) { - if (exceptionNameObjectIdCollection == null) - exceptionNameObjectIdCollection = new HashMap<>(); - - ExceptionInfo ex = test.getExceptionInfoList().get(0); - - ObjectId exceptionId; - doc = new Document("report", reportId) - .append("project", projectId) - .append("name", ex.getExceptionName()); - - FindIterable iterable = exceptionCollection.find(doc); - Document docException = iterable.first(); - - // check if a matching exception name is available in 'Exception' collection (MongoDB) - // if a matching exception name is found, associate with this exception's ObjectId - if (!exceptionNameObjectIdCollection.containsKey(ex.getExceptionName())) { - if (docException != null) { - exceptionNameObjectIdCollection.put(ex.getExceptionName(), docException.getObjectId("_id")); - } else { - doc = new Document("project", projectId) - .append("report", reportId) - .append("name", ex.getExceptionName()) - .append("stacktrace", ex.getStackTrace()) - .append("testCount", 0); - - exceptionCollection.insertOne(doc); - - exceptionId = MongoUtil.getId(doc); - docException = exceptionCollection.find(new Document("_id", exceptionId)).first(); - - exceptionNameObjectIdCollection.put(ex.getExceptionName(), exceptionId); - } - } - - Integer testCount = ((Integer) (docException.get("testCount"))) + 1; - doc = new Document("testCount", testCount); - - exceptionCollection.updateOne( - new Document("_id", docException.getObjectId("_id")), - new Document("$set", doc)); - - doc = new Document("exception", exceptionNameObjectIdCollection.get(ex.getExceptionName())); - - testCollection.updateOne( - new Document("_id", test.getObjectId()), - new Document("$set", doc)); - updateTestDesc(test); - } - - endTestRecursive(test); - } - - private void endTestRecursive(Test test) { - Document doc = new Document("status", test.getStatus().toString()) - .append("endTime", test.getEndTime()) - .append("duration", test.getRunDurationMillis()) - .append("leaf", test.getNodeContext().size()==0) - .append("childNodesLength", test.getNodeContext().size()) - .append("categorized", test.hasCategory()) - .append("description", test.getDescription()); - - testCollection.updateOne( - new Document("_id", test.getObjectId()), - new Document("$set", doc)); - - if (test.getLevel() > 0) { - endTestRecursive(test.getParent()); - } - } - - public void assignAttribute(Test test, TestAttribute attribute, Map nameObjectIdCollection, - MongoCollection mongoCollection, TestAttributeTestContextProvider attributeContext) { - } - - @Override - public void onCategoryAssigned(Test test, Category category) { - assignAttribute(test, category, categoryNameObjectIdCollection, categoryCollection, categoryContext); - } - - @Override - public void onAuthorAssigned(Test test, Author author) { - assignAttribute(test, author, authorNameObjectIdCollection, authorCollection, authorContext); - } - - private KlovMediaStorageHandler mediaStorageHandler; - - @Override - public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { - saveScreenCapture(test, screenCapture); - } - - @Override - public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { - screenCapture.setLogObjectId(log.getObjectId()); - saveScreenCapture(log, screenCapture); - } - - private void saveScreenCapture(BasicMongoReportElement el, ScreenCapture screenCapture) throws IOException { - if (mediaStorageHandler == null) { - KlovMedia klovMedia = new KlovMedia(projectId, reportId, mediaCollection); - mediaStorageHandler = new KlovMediaStorageHandler(url, klovMedia); - } - mediaStorageHandler.saveScreenCapture(el, screenCapture); - } - - @Override - public void onScreencastAdded(Test test, Screencast screencast) throws IOException { } - - /** - * Returns the active Project ID - * - * @return A {@link ObjectId} object - */ - public ObjectId getProjectId() { - return projectId; - } - - /** - * Returns the active Report ID - * - * @return A {@link ObjectId} object - */ - public ObjectId getReportId() { - return reportId; - } + doc.append("details", log.getDetails() + log.getScreenCaptureContext().getFirst().getSource()); + } + + logCollection.insertOne(doc); + + ObjectId logId = MongoUtil.getId(doc); + log.setObjectId(logId); + + // check for exceptions.. + if (test.hasException()) { + if (exceptionNameObjectIdCollection == null) + exceptionNameObjectIdCollection = new HashMap<>(); + + ExceptionInfo ex = test.getExceptionInfoList().get(0); + + ObjectId exceptionId; + doc = new Document("report", reportId).append("project", projectId).append("name", ex.getExceptionName()); + + FindIterable iterable = exceptionCollection.find(doc); + Document docException = iterable.first(); + + // check if a matching exception name is available in 'Exception' collection + // (MongoDB) + // if a matching exception name is found, associate with this exception's + // ObjectId + if (!exceptionNameObjectIdCollection.containsKey(ex.getExceptionName())) { + if (docException != null) { + exceptionNameObjectIdCollection.put(ex.getExceptionName(), docException.getObjectId("_id")); + } else { + doc = new Document("project", projectId).append("report", reportId) + .append("name", ex.getExceptionName()).append("stacktrace", ex.getStackTrace()) + .append("testCount", 0); + + exceptionCollection.insertOne(doc); + + exceptionId = MongoUtil.getId(doc); + docException = exceptionCollection.find(new Document("_id", exceptionId)).first(); + + exceptionNameObjectIdCollection.put(ex.getExceptionName(), exceptionId); + } + } + + Integer testCount = ((Integer) (docException.get("testCount"))) + 1; + doc = new Document("testCount", testCount); + + exceptionCollection.updateOne(new Document("_id", docException.getObjectId("_id")), + new Document("$set", doc)); + + doc = new Document("exception", exceptionNameObjectIdCollection.get(ex.getExceptionName())); + + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + updateTestDesc(test); + } + + endTestRecursive(test); + } + + private void endTestRecursive(Test test) { + Document doc = new Document("status", test.getStatus().toString()).append("endTime", test.getEndTime()) + .append("duration", test.getRunDurationMillis()).append("leaf", test.getNodeContext().size() == 0) + .append("childNodesLength", test.getNodeContext().size()).append("categorized", test.hasCategory()) + .append("description", test.getDescription()); + + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + + if (test.getLevel() > 0) { + endTestRecursive(test.getParent()); + } + } + + public void assignAttribute(Test test, TestAttribute attribute, + Map nameObjectIdCollection, MongoCollection mongoCollection, + TestAttributeTestContextProvider attributeContext) { + } @Override - public void onTestRemoved(Test test) { } + public void onCategoryAssigned(Test test, Category category) { + assignAttribute(test, category, categoryNameObjectIdCollection, categoryCollection, categoryContext); + } + + @Override + public void onAuthorAssigned(Test test, Author author) { + assignAttribute(test, author, authorNameObjectIdCollection, authorCollection, authorContext); + } + + private KlovMediaStorageHandler mediaStorageHandler; + + @Override + public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { + saveScreenCapture(test, screenCapture); + } + + @Override + public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { + screenCapture.setLogObjectId(log.getObjectId()); + saveScreenCapture(log, screenCapture); + } + + private void saveScreenCapture(BasicMongoReportElement el, ScreenCapture screenCapture) throws IOException { + if (mediaStorageHandler == null) { + KlovMedia klovMedia = new KlovMedia(projectId, reportId, mediaCollection); + mediaStorageHandler = new KlovMediaStorageHandler(url, klovMedia); + } + mediaStorageHandler.saveScreenCapture(el, screenCapture); + } + + @Override + public void onScreencastAdded(Test test, Screencast screencast) throws IOException { + } + + /** + * Returns the active Project ID + * + * @return A {@link ObjectId} object + */ + public ObjectId getProjectId() { + return projectId; + } + + /** + * Returns the active Report ID + * + * @return A {@link ObjectId} object + */ + public ObjectId getReportId() { + return reportId; + } + + @Override + public void onTestRemoved(Test test) { + } @Override public void onDeviceAssigned(Test test, Device device) { @@ -714,5 +678,5 @@ public void onDeviceAssigned(Test test, Device device) { public String getReporterName() { return REPORTER_NAME; } - + } diff --git a/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java b/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java index 888bb84..140d33a 100644 --- a/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java +++ b/src/test/java/com/aventstack/extentreports/reporter/HtmlBasicFileReporterConfigurationTest.java @@ -9,102 +9,102 @@ public class HtmlBasicFileReporterConfigurationTest extends Base { - @Test - public void htmlReporterHasInitialConfig(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - Assert.assertFalse(html.getConfigContext().isEmpty()); - } - - @Test - public void testHtmlReporterUserConfigInitialCSSNull(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String v = html.config().getConfigMap().get("styles"); - Assert.assertNull(v); - } - - @Test - public void testHtmlReporterUserConfigCSSHasValue(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String css = ".dark{background:black;}"; - html.config().setCSS(css); - String v = html.config().getConfigMap().get("styles"); - Assert.assertFalse(v.isEmpty()); - } - - @Test - public void testHtmlReporterUserConfigCSSValue(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String css = ".dark{background:black;}"; - html.config().setCSS(css); - String v = html.config().getConfigMap().get("styles"); - Assert.assertEquals(v, css); - } - - @Test - public void testHtmlReporterUserConfigInitialJSNull(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String v = html.config().getConfigMap().get("scripts"); - Assert.assertNull(v); - } - - @Test - public void testHtmlReporterUserConfigJSHasValue(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - html.config().setJS("alert('');"); - String v = html.config().getConfigMap().get("scripts"); - Assert.assertFalse(v.isEmpty()); - } - - @Test - public void testHtmlReporterUserConfigJSValue(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String js = "alert('');"; - html.config().setJS(js); - String v = html.config().getConfigMap().get("scripts"); - Assert.assertEquals(v, js); - } - - @Test - public void documentTitleInitialValueTest(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - Assert.assertFalse(html.getConfigContext().getValue("documentTitle").toString().isEmpty()); - } - - @Test - public void documentTitleInitialUserValueTest(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String v = html.config().getConfigMap().get("documentTitle"); - Assert.assertNull(v); - } - - @Test - public void documentTitleUserValueTest(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String docTitle = "test"; - html.config().setDocumentTitle(docTitle); - String v = html.config().getConfigMap().get("documentTitle"); - Assert.assertEquals(v, docTitle); - } - - @Test - public void encodingInitialValueTest(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - Assert.assertTrue(html.getConfigContext().getValue("encoding").toString().equalsIgnoreCase("utf-8")); - } - - @Test - public void encodingInitialUserValueTest(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String v = html.config().getConfigMap().get("encoding"); - Assert.assertNull(v); - } - - @Test - public void encodingUserValueTest(Method method) { - ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); - String encoding = "utf-16"; - html.config().setEncoding(encoding); - String v = html.config().getConfigMap().get("encoding"); - Assert.assertEquals(v, encoding); - } + @Test + public void htmlReporterHasInitialConfig(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + Assert.assertFalse(html.getConfigContext().isEmpty()); + } + + @Test + public void testHtmlReporterUserConfigInitialCSSNull(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String v = html.config().getConfigMap().get("styles"); + Assert.assertNull(v); + } + + @Test + public void testHtmlReporterUserConfigCSSHasValue(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String css = ".dark{background:black;}"; + html.config().setCSS(css); + String v = html.config().getConfigMap().get("styles"); + Assert.assertFalse(v.isEmpty()); + } + + @Test + public void testHtmlReporterUserConfigCSSValue(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String css = ".dark{background:black;}"; + html.config().setCSS(css); + String v = html.config().getConfigMap().get("styles"); + Assert.assertEquals(v, css); + } + + @Test + public void testHtmlReporterUserConfigInitialJSNull(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String v = html.config().getConfigMap().get("scripts"); + Assert.assertNull(v); + } + + @Test + public void testHtmlReporterUserConfigJSHasValue(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + html.config().setJS("alert('');"); + String v = html.config().getConfigMap().get("scripts"); + Assert.assertFalse(v.isEmpty()); + } + + @Test + public void testHtmlReporterUserConfigJSValue(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String js = "alert('');"; + html.config().setJS(js); + String v = html.config().getConfigMap().get("scripts"); + Assert.assertEquals(v, js); + } + + @Test + public void documentTitleInitialValueTest(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + Assert.assertFalse(html.getConfigContext().getValue("documentTitle").toString().isEmpty()); + } + + @Test + public void documentTitleInitialUserValueTest(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String v = html.config().getConfigMap().get("documentTitle"); + Assert.assertNull(v); + } + + @Test + public void documentTitleUserValueTest(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String docTitle = "test"; + html.config().setDocumentTitle(docTitle); + String v = html.config().getConfigMap().get("documentTitle"); + Assert.assertEquals(v, docTitle); + } + + @Test + public void encodingInitialValueTest(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + Assert.assertTrue(html.getConfigContext().getValue("encoding").toString().equalsIgnoreCase("utf-8")); + } + + @Test + public void encodingInitialUserValueTest(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String v = html.config().getConfigMap().get("encoding"); + Assert.assertNull(v); + } + + @Test + public void encodingUserValueTest(Method method) { + ExtentHtmlReporter html = new ExtentHtmlReporter(method.getName() + ".html"); + String encoding = "utf-16"; + html.config().setEncoding(encoding); + String v = html.config().getConfigMap().get("encoding"); + Assert.assertEquals(v, encoding); + } } diff --git a/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java b/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java index 8e7be1d..c7d9308 100644 --- a/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java +++ b/src/test/java/com/aventstack/extentreports/reporter/HtmlConfigurableReporterTest.java @@ -9,58 +9,57 @@ import com.aventstack.extentreports.Base; public class HtmlConfigurableReporterTest extends Base { - - private static final String CONFIG_PATH = "src/test/resources/html-config.xml"; - private static final String THEME = "dark"; - private static final String ENCODING = "utf-8"; - private static final String DOCUMENT_TITLE = "Extent Framework"; - private static final String REPORT_NAME = "Build 1"; - private static final String TIMESTAMP_FORMAT = "MMM dd, yyyy HH:mm:ss"; - private static final String CSS = ".test.active { border: 1px solid #ccc; }"; - private static final String JS = "$('.test').click(function() { console.log('test'); });"; - - private ExtentHtmlReporter html; - - @BeforeClass - public void beforeClass() { - html = new ExtentHtmlReporter("Extent.html"); - html.loadXMLConfig(CONFIG_PATH); - } - - @Test - public void testTheme() { - Assert.assertEquals(html.getConfigContext().getValue("theme"), THEME); - } - - @Test - public void testEncoding() { - html.getConfigContext().printMapForTest(); - Assert.assertTrue(String.valueOf(html.getConfigContext().getValue("encoding")).equalsIgnoreCase(ENCODING)); - } - - @Test - public void testDocumentTitle() { - Assert.assertEquals(html.getConfigContext().getValue("documentTitle"), DOCUMENT_TITLE); - } - - @Test - public void testReportName() { - Assert.assertEquals(html.getConfigContext().getValue("reportName"), REPORT_NAME); - } - - @Test - public void testTimestampFormat() { - Assert.assertEquals(html.getConfigContext().getValue("timeStampFormat"), TIMESTAMP_FORMAT); - } - - @Test - public void testCSS() { - Assert.assertTrue(html.getConfigContext().getValue("styles").toString().contains(CSS)); - } - - @Test - public void testJS() { - Assert.assertTrue(html.getConfigContext().getValue("scripts").toString().contains(JS)); - } - + + private static final String CONFIG_PATH = "src/test/resources/html-config.xml"; + private static final String THEME = "dark"; + private static final String ENCODING = "utf-8"; + private static final String DOCUMENT_TITLE = "Extent Framework"; + private static final String REPORT_NAME = "Build 1"; + private static final String TIMESTAMP_FORMAT = "MMM dd, yyyy HH:mm:ss"; + private static final String CSS = ".test.active { border: 1px solid #ccc; }"; + private static final String JS = "$('.test').click(function() { console.log('test'); });"; + + private ExtentHtmlReporter html; + + @BeforeClass + public void beforeClass() { + html = new ExtentHtmlReporter("Extent.html"); + html.loadXMLConfig(CONFIG_PATH); + } + + @Test + public void testTheme() { + Assert.assertEquals(html.getConfigContext().getValue("theme"), THEME); + } + + @Test + public void testEncoding() { + Assert.assertTrue(String.valueOf(html.getConfigContext().getValue("encoding")).equalsIgnoreCase(ENCODING)); + } + + @Test + public void testDocumentTitle() { + Assert.assertEquals(html.getConfigContext().getValue("documentTitle"), DOCUMENT_TITLE); + } + + @Test + public void testReportName() { + Assert.assertEquals(html.getConfigContext().getValue("reportName"), REPORT_NAME); + } + + @Test + public void testTimestampFormat() { + Assert.assertEquals(html.getConfigContext().getValue("timeStampFormat"), TIMESTAMP_FORMAT); + } + + @Test + public void testCSS() { + Assert.assertTrue(html.getConfigContext().getValue("styles").toString().contains(CSS)); + } + + @Test + public void testJS() { + Assert.assertTrue(html.getConfigContext().getValue("scripts").toString().contains(JS)); + } + } diff --git a/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java b/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java index 8a9ec89..2a9464b 100644 --- a/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java +++ b/src/test/java/com/aventstack/extentreports/reporter/LoggerBasicFileReporterConfigurationTest2.java @@ -9,102 +9,102 @@ public class LoggerBasicFileReporterConfigurationTest2 extends Base { - @Test - public void htmlReporterHasInitialConfig(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - Assert.assertFalse(logger.getConfigContext().isEmpty()); - } - - @Test - public void testHtmlReporterUserConfigInitialCSSNull(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String v = logger.config().getConfigMap().get("styles"); - Assert.assertNull(v); - } - - @Test - public void testHtmlReporterUserConfigCSSHasValue(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String css = ".dark{background:black;}"; - logger.config().setCSS(css); - String v = logger.config().getConfigMap().get("styles"); - Assert.assertFalse(v.isEmpty()); - } - - @Test - public void testHtmlReporterUserConfigCSSValue(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String css = ".dark{background:black;}"; - logger.config().setCSS(css); - String v = logger.config().getConfigMap().get("styles"); - Assert.assertEquals(v, css); - } - - @Test - public void testHtmlReporterUserConfigInitialJSNull(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String v = logger.config().getConfigMap().get("scripts"); - Assert.assertNull(v); - } - - @Test - public void testHtmlReporterUserConfigJSHasValue(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - logger.config().setJS("alert('');"); - String v = logger.config().getConfigMap().get("scripts"); - Assert.assertFalse(v.isEmpty()); - } - - @Test - public void testHtmlReporterUserConfigJSValue(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String js = "alert('');"; - logger.config().setJS(js); - String v = logger.config().getConfigMap().get("scripts"); - Assert.assertEquals(v, js); - } - - @Test - public void documentTitleInitialValueTest(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - Assert.assertFalse(logger.getConfigContext().getValue("documentTitle").toString().isEmpty()); - } - - @Test - public void documentTitleInitialUserValueTest(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String v = logger.config().getConfigMap().get("documentTitle"); - Assert.assertNull(v); - } - - @Test - public void documentTitleUserValueTest(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String docTitle = "test"; - logger.config().setDocumentTitle(docTitle); - String v = logger.config().getConfigMap().get("documentTitle"); - Assert.assertEquals(v, docTitle); - } - - @Test - public void encodingInitialValueTest(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - Assert.assertTrue(logger.getConfigContext().getValue("encoding").toString().equalsIgnoreCase("utf-8")); - } - - @Test - public void encodingInitialUserValueTest(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String v = logger.config().getConfigMap().get("encoding"); - Assert.assertNull(v); - } - - @Test - public void encodingUserValueTest(Method method) { - ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); - String encoding = "utf-16"; - logger.config().setEncoding(encoding); - String v = logger.config().getConfigMap().get("encoding"); - Assert.assertEquals(v, encoding); - } + @Test + public void htmlReporterHasInitialConfig(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + Assert.assertFalse(logger.getConfigContext().isEmpty()); + } + + @Test + public void testHtmlReporterUserConfigInitialCSSNull(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String v = logger.config().getConfigMap().get("styles"); + Assert.assertNull(v); + } + + @Test + public void testHtmlReporterUserConfigCSSHasValue(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String css = ".dark{background:black;}"; + logger.config().setCSS(css); + String v = logger.config().getConfigMap().get("styles"); + Assert.assertFalse(v.isEmpty()); + } + + @Test + public void testHtmlReporterUserConfigCSSValue(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String css = ".dark{background:black;}"; + logger.config().setCSS(css); + String v = logger.config().getConfigMap().get("styles"); + Assert.assertEquals(v, css); + } + + @Test + public void testHtmlReporterUserConfigInitialJSNull(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String v = logger.config().getConfigMap().get("scripts"); + Assert.assertNull(v); + } + + @Test + public void testHtmlReporterUserConfigJSHasValue(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + logger.config().setJS("alert('');"); + String v = logger.config().getConfigMap().get("scripts"); + Assert.assertFalse(v.isEmpty()); + } + + @Test + public void testHtmlReporterUserConfigJSValue(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String js = "alert('');"; + logger.config().setJS(js); + String v = logger.config().getConfigMap().get("scripts"); + Assert.assertEquals(v, js); + } + + @Test + public void documentTitleInitialValueTest(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + Assert.assertFalse(logger.getConfigContext().getValue("documentTitle").toString().isEmpty()); + } + + @Test + public void documentTitleInitialUserValueTest(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String v = logger.config().getConfigMap().get("documentTitle"); + Assert.assertNull(v); + } + + @Test + public void documentTitleUserValueTest(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String docTitle = "test"; + logger.config().setDocumentTitle(docTitle); + String v = logger.config().getConfigMap().get("documentTitle"); + Assert.assertEquals(v, docTitle); + } + + @Test + public void encodingInitialValueTest(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + Assert.assertTrue(logger.getConfigContext().getValue("encoding").toString().equalsIgnoreCase("utf-8")); + } + + @Test + public void encodingInitialUserValueTest(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String v = logger.config().getConfigMap().get("encoding"); + Assert.assertNull(v); + } + + @Test + public void encodingUserValueTest(Method method) { + ExtentLoggerReporter logger = new ExtentLoggerReporter(method.getName() + ".html"); + String encoding = "utf-16"; + logger.config().setEncoding(encoding); + String v = logger.config().getConfigMap().get("encoding"); + Assert.assertEquals(v, encoding); + } } From 92d528ff7f3bb70d791330feeb7634f8ae77089b Mon Sep 17 00:00:00 2001 From: Virender Date: Thu, 7 Mar 2019 23:49:51 +0530 Subject: [PATCH 10/77] Removing unused variable and methods from AbstractReporter --- .../reporter/AbstractReporter.java | 10 +- .../reporter/BasicFileReporter.java | 1 - .../api/RemoveStartedTestsFromExtentTest.java | 98 +++++++++---------- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java index 36332b7..0d65d40 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java @@ -18,14 +18,14 @@ public abstract class AbstractReporter protected List levels; protected Date startTime = Calendar.getInstance().getTime(); protected Date endTime = startTime; - protected List statusList; + //protected List statusList; private AnalysisStrategy strategy = AnalysisStrategy.TEST; public void flush(ReportAggregates reportAggregates) { this.startTime = reportAggregates.getStartTime(); this.endTime = reportAggregates.getEndTime(); - this.statusList = reportAggregates.getStatusList(); + //this.statusList = reportAggregates.getStatusList(); } protected Date getStartTime() { @@ -67,8 +67,8 @@ public String getLongRunDuration() { return hours + "h " + mins + "m " + secs + "s+" + ms + "ms"; } - public List getStatusList() { - return statusList; - } +// public List getStatusList() { +// return statusList; +// } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index 10e387a..476a71c 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -199,7 +199,6 @@ public ReportStatusStats getReportStatusStats() { return stats; } - @Override public List getStatusList() { return statusList; } diff --git a/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java b/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java index e0fbeb9..58dbd46 100644 --- a/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java +++ b/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java @@ -15,54 +15,54 @@ public class RemoveStartedTestsFromExtentTest extends Base { - private AbstractReporter reporter; - - @BeforeMethod - public void beforeMethod() { - setup(); - - Optional reporter = extent - .getStartedReporters() - .stream() - .filter(x -> x instanceof AbstractReporter) - .map(x -> (AbstractReporter)x) - .findFirst(); - if (reporter.get() != null) - this.reporter = reporter.get(); - } - - @Test - public void removeAnErroredTest(Method method) { - if (reporter == null) - throw new SkipException("No Reporters were started."); - - extent.createTest("Pass").pass("Hello"); - ExtentTest test = extent.createTest("Error").error("Hello"); - extent.removeTest(test); - extent.flush(); - - boolean b = reporter.getStatusList().contains(Status.ERROR); - Assert.assertFalse(b, "Error status was removed, collection still contains it"); - - b = reporter.getStatusList().contains(Status.PASS); - Assert.assertTrue(b, "Pass status was not removed, collection does not contain it"); - } - - @Test - public void removeAPassedTest(Method method) { - if (reporter == null) - throw new SkipException("No Reporters were started."); - - ExtentTest test = extent.createTest("Pass").pass("Hello"); - extent.createTest("Error").error("Hello"); - extent.removeTest(test); - extent.flush(); - - boolean b = reporter.getStatusList().contains(Status.PASS); - Assert.assertFalse(b, "Pass status was removed, collection still contains it"); - - b = reporter.getStatusList().contains(Status.ERROR); - Assert.assertTrue(b, "Error status was not removed, collection does not contain it"); - } +// private AbstractReporter reporter; +// +// @BeforeMethod +// public void beforeMethod() { +// setup(); +// +// Optional reporter = extent +// .getStartedReporters() +// .stream() +// .filter(x -> x instanceof AbstractReporter) +// .map(x -> (AbstractReporter)x) +// .findFirst(); +// if (reporter.get() != null) +// this.reporter = reporter.get(); +// } +// +// @Test +// public void removeAnErroredTest(Method method) { +// if (reporter == null) +// throw new SkipException("No Reporters were started."); +// +// extent.createTest("Pass").pass("Hello"); +// ExtentTest test = extent.createTest("Error").error("Hello"); +// extent.removeTest(test); +// extent.flush(); +// +// boolean b = reporter.getStatusList().contains(Status.ERROR); +// Assert.assertFalse(b, "Error status was removed, collection still contains it"); +// +// b = reporter.getStatusList().contains(Status.PASS); +// Assert.assertTrue(b, "Pass status was not removed, collection does not contain it"); +// } +// +// @Test +// public void removeAPassedTest(Method method) { +// if (reporter == null) +// throw new SkipException("No Reporters were started."); +// +// ExtentTest test = extent.createTest("Pass").pass("Hello"); +// extent.createTest("Error").error("Hello"); +// extent.removeTest(test); +// extent.flush(); +// +// boolean b = reporter.getStatusList().contains(Status.PASS); +// Assert.assertFalse(b, "Pass status was removed, collection still contains it"); +// +// b = reporter.getStatusList().contains(Status.ERROR); +// Assert.assertTrue(b, "Error status was not removed, collection does not contain it"); +// } } From bc16f2c4a9a4cf7e9aa6f31bc96bd9861fb8e346 Mon Sep 17 00:00:00 2001 From: Virender Date: Thu, 7 Mar 2019 23:51:37 +0530 Subject: [PATCH 11/77] Removing levels variable from AbstractReporter --- .../com/aventstack/extentreports/reporter/AbstractReporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java index 0d65d40..cb7e838 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java @@ -15,7 +15,7 @@ public abstract class AbstractReporter extends ConfigurableReporter { - protected List levels; + //protected List levels; protected Date startTime = Calendar.getInstance().getTime(); protected Date endTime = startTime; //protected List statusList; From 80518fc485f2a99c94aeb8af8160a5bfb6b6099c Mon Sep 17 00:00:00 2001 From: Virender Date: Thu, 7 Mar 2019 23:54:27 +0530 Subject: [PATCH 12/77] Removing comments --- .../reporter/AbstractReporter.java | 8 --- .../api/RemoveStartedTestsFromExtentTest.java | 52 +------------------ 2 files changed, 1 insertion(+), 59 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java index cb7e838..2a61c82 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java @@ -15,17 +15,14 @@ public abstract class AbstractReporter extends ConfigurableReporter { - //protected List levels; protected Date startTime = Calendar.getInstance().getTime(); protected Date endTime = startTime; - //protected List statusList; private AnalysisStrategy strategy = AnalysisStrategy.TEST; public void flush(ReportAggregates reportAggregates) { this.startTime = reportAggregates.getStartTime(); this.endTime = reportAggregates.getEndTime(); - //this.statusList = reportAggregates.getStatusList(); } protected Date getStartTime() { @@ -66,9 +63,4 @@ public String getLongRunDuration() { return hours + "h " + mins + "m " + secs + "s+" + ms + "ms"; } - -// public List getStatusList() { -// return statusList; -// } - } diff --git a/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java b/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java index 58dbd46..86536d8 100644 --- a/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java +++ b/src/test/java/com/aventstack/extentreports/api/RemoveStartedTestsFromExtentTest.java @@ -14,55 +14,5 @@ import com.aventstack.extentreports.reporter.AbstractReporter; public class RemoveStartedTestsFromExtentTest extends Base { - -// private AbstractReporter reporter; -// -// @BeforeMethod -// public void beforeMethod() { -// setup(); -// -// Optional reporter = extent -// .getStartedReporters() -// .stream() -// .filter(x -> x instanceof AbstractReporter) -// .map(x -> (AbstractReporter)x) -// .findFirst(); -// if (reporter.get() != null) -// this.reporter = reporter.get(); -// } -// -// @Test -// public void removeAnErroredTest(Method method) { -// if (reporter == null) -// throw new SkipException("No Reporters were started."); -// -// extent.createTest("Pass").pass("Hello"); -// ExtentTest test = extent.createTest("Error").error("Hello"); -// extent.removeTest(test); -// extent.flush(); -// -// boolean b = reporter.getStatusList().contains(Status.ERROR); -// Assert.assertFalse(b, "Error status was removed, collection still contains it"); -// -// b = reporter.getStatusList().contains(Status.PASS); -// Assert.assertTrue(b, "Pass status was not removed, collection does not contain it"); -// } -// -// @Test -// public void removeAPassedTest(Method method) { -// if (reporter == null) -// throw new SkipException("No Reporters were started."); -// -// ExtentTest test = extent.createTest("Pass").pass("Hello"); -// extent.createTest("Error").error("Hello"); -// extent.removeTest(test); -// extent.flush(); -// -// boolean b = reporter.getStatusList().contains(Status.PASS); -// Assert.assertFalse(b, "Pass status was removed, collection still contains it"); -// -// b = reporter.getStatusList().contains(Status.ERROR); -// Assert.assertTrue(b, "Error status was not removed, collection does not contain it"); -// } - + // Add Tests from test removal functionality. TODO: virenv } From 9e5fb01eb8ae2f363baf14149a26292eb7756ea9 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sat, 16 Mar 2019 20:39:22 -0700 Subject: [PATCH 13/77] #67 --- pom.xml | 2 +- src/main/java/com/aventstack/extentreports/TestRemover.java | 1 + src/main/java/com/aventstack/extentreports/model/Test.java | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb167f9..e6b9b6e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.aventstack extentreports - 4.0.9 + 4.0.10-SNAPSHOT extentreports www.extentreports.com diff --git a/src/main/java/com/aventstack/extentreports/TestRemover.java b/src/main/java/com/aventstack/extentreports/TestRemover.java index e442fd2..296c70c 100644 --- a/src/main/java/com/aventstack/extentreports/TestRemover.java +++ b/src/main/java/com/aventstack/extentreports/TestRemover.java @@ -24,6 +24,7 @@ private TestRemover() { } public static void remove(List testList, Test test) { removed = false; findAndRemoveTest(testList, test); + testList.forEach(Test::end); } /** diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index b1b8f97..7d4cda5 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -275,6 +275,7 @@ private synchronized void updateStatus(Status logStatus) { } public void end() { + setStatus(Status.PASS); updateTestStatusRecursive(this); endChildrenRecursive(this); From 5a6329a18bc4b480693d226bf66ae7efd83a0263 Mon Sep 17 00:00:00 2001 From: Virender Singh Date: Sat, 30 Mar 2019 17:57:57 +0530 Subject: [PATCH 14/77] Removing the usage of statusMap from ExtentObservable class plus some minor changes for code accuracy --- .../extentreports/ExtentObservable.java | 31 ++++++++++--------- .../reporter/BasicFileReporter.java | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index b7844d7..d32c93d 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -7,6 +7,7 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import java.util.stream.Collectors; import com.aventstack.extentreports.model.Author; @@ -162,11 +163,6 @@ abstract class ExtentObservable */ private List statusList = new ArrayList<>(); - /** - * Contains status as keys, which are translated over to statusList - */ - private Map statusMap = new EnumMap<>(Status.class); - protected ExtentObservable() { } /** @@ -186,8 +182,11 @@ protected void register(ExtentReporter reporter) { * @param reporter {@link ExtentReporter} reporter to unsubscribe */ protected void deregister(ExtentReporter reporter) { - reporter.stop(); - reporterList.remove(reporter); + + if(reporterList.contains((Object) reporter)){ + reporter.stop(); + reporterList.remove(reporter); + } } /** @@ -266,10 +265,8 @@ private void refreshReportStats() { * Refresh and notify all reports of distinct status assigned to tests */ private synchronized void refreshStatusList() { - statusMap.clear(); statusList.clear(); refreshStatusList(testList); - statusMap.forEach((k,v) -> statusList.add(k)); } /** @@ -281,11 +278,17 @@ private synchronized void refreshStatusList(List list) { if (list == null || list.isEmpty()) return; - list.stream() - .map(Test::getStatus) - .distinct() - .collect(Collectors.toList()) - .forEach(x -> statusMap.put(x, false)); + // It is not necessary to go through the stream support of + // Java 8 here. This brings in a hard binding with Java version. + // As we have used streams all across, this should be fine. + list.stream().forEach(new Consumer() { + @Override + public void accept(Test t) { + if(!statusList.contains((Object) t)){ + statusList.add(t.getStatus()); + } + } + }); list.forEach(x -> refreshStatusList(x.getNodeContext().getAll())); } diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index 476a71c..fd32d6b 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -288,7 +288,7 @@ public boolean containsStatus(String status) { } public boolean containsStatus(Status status) { - return getStatusList() != null && !getStatusList().isEmpty() && getStatusList().contains(status); + return getStatusList() != null && getStatusList().contains(status); } protected void processTemplate(Template template, File outputFile) throws TemplateException, IOException { From 4b315bc306de44b2e710fcc969efac30e3e35024 Mon Sep 17 00:00:00 2001 From: Virender Date: Tue, 2 Apr 2019 22:43:45 +0530 Subject: [PATCH 15/77] Moving the code from holding a List to Set. Also changing the interface methods to talk in terms of Collections instead of specific Collection implementations --- .../extentreports/ExtentObservable.java | 25 ++++++------------- .../extentreports/ReportAggregates.java | 14 ++++++----- .../ReportAggregatesBuilder.java | 9 ++++--- .../com/aventstack/extentreports/Status.java | 7 +++--- .../reporter/BasicFileReporter.java | 11 ++++---- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index d32c93d..1c82a2d 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -5,8 +5,10 @@ import java.util.Calendar; import java.util.Date; import java.util.EnumMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -134,7 +136,7 @@ abstract class ExtentObservable private ReportStatusStats stats = new ReportStatusStats(strategy); /** - * A unique list of status tests are marked with + * A Set of status tests are marked with * *

* Consider a report having 10 tests: @@ -161,7 +163,7 @@ abstract class ExtentObservable *

  • FAIL
  • * */ - private List statusList = new ArrayList<>(); + private Set statusSet = new HashSet(); protected ExtentObservable() { } @@ -265,7 +267,7 @@ private void refreshReportStats() { * Refresh and notify all reports of distinct status assigned to tests */ private synchronized void refreshStatusList() { - statusList.clear(); + statusSet.clear(); refreshStatusList(testList); } @@ -277,19 +279,8 @@ private synchronized void refreshStatusList() { private synchronized void refreshStatusList(List list) { if (list == null || list.isEmpty()) return; - - // It is not necessary to go through the stream support of - // Java 8 here. This brings in a hard binding with Java version. - // As we have used streams all across, this should be fine. - list.stream().forEach(new Consumer() { - @Override - public void accept(Test t) { - if(!statusList.contains((Object) t)){ - statusList.add(t.getStatus()); - } - } - }); - + + list.forEach(x -> statusSet.add(x.getStatus())); list.forEach(x -> refreshStatusList(x.getNodeContext().getAll())); } @@ -536,7 +527,7 @@ private synchronized void notifyReporters() { .setDeviceContext(deviceContext) .setExceptionContext(exceptionContextBuilder) .setReportStatusStats(stats) - .setStatusList(statusList) + .setStatusCollection(statusSet) .setSystemAttributeContext(systemAttributeContext) .setTestList(testList) .setTestRunnerLogs(testRunnerLogs) diff --git a/src/main/java/com/aventstack/extentreports/ReportAggregates.java b/src/main/java/com/aventstack/extentreports/ReportAggregates.java index de16347..931de9f 100644 --- a/src/main/java/com/aventstack/extentreports/ReportAggregates.java +++ b/src/main/java/com/aventstack/extentreports/ReportAggregates.java @@ -1,7 +1,9 @@ package com.aventstack.extentreports; +import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.Set; import com.aventstack.extentreports.model.Author; import com.aventstack.extentreports.model.Category; @@ -22,7 +24,7 @@ public class ReportAggregates { private ExceptionTestContextImpl exceptionContext; private SystemAttributeContext systemAttributeContext; private ReportStatusStats reportStatusStats; - private List statusList; + private Collection statusCollection; private Date startTime; private Date endTime; @@ -43,7 +45,7 @@ public void setEndTime(Date endTime) { } public Status getStatus() { - return Status.getHighestStatus(getStatusList()); + return Status.getHighestStatus(getStatusCollection()); } public List getTestList() { @@ -110,12 +112,12 @@ public void setReportStatusStats(ReportStatusStats reportStatusStats) { this.reportStatusStats = reportStatusStats; } - public List getStatusList() { - return statusList; + public Collection getStatusCollection() { + return statusCollection; } - public void setStatusList(List statusList) { - this.statusList = statusList; + public void setStatusCollection(Collection statusCollection) { + this.statusCollection = statusCollection; } } diff --git a/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java b/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java index d2e7084..a7a07d5 100644 --- a/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java +++ b/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java @@ -1,5 +1,6 @@ package com.aventstack.extentreports; +import java.util.Collection; import java.util.Date; import java.util.List; @@ -22,7 +23,7 @@ public class ReportAggregatesBuilder { private ExceptionTestContextImpl exceptionContext; private SystemAttributeContext systemAttributeContext; private ReportStatusStats reportStatusStats; - private List statusList; + private Collection statusCollection; private Date startTime; private Date endTime; @@ -36,7 +37,7 @@ public ReportAggregates build() { aggregates.setExceptionContext(exceptionContext); aggregates.setSystemAttributeContext(systemAttributeContext); aggregates.setReportStatusStats(reportStatusStats); - aggregates.setStatusList(statusList); + aggregates.setStatusCollection(statusCollection); aggregates.setStartTime(startTime); aggregates.setEndTime(endTime); return aggregates; @@ -82,8 +83,8 @@ public ReportAggregatesBuilder setReportStatusStats(ReportStatusStats reportStat return this; } - public ReportAggregatesBuilder setStatusList(List statusList) { - this.statusList = statusList; + public ReportAggregatesBuilder setStatusCollection(Collection statusCollection) { + this.statusCollection = statusCollection; return this; } diff --git a/src/main/java/com/aventstack/extentreports/Status.java b/src/main/java/com/aventstack/extentreports/Status.java index 8ab30bd..94a17aa 100644 --- a/src/main/java/com/aventstack/extentreports/Status.java +++ b/src/main/java/com/aventstack/extentreports/Status.java @@ -2,6 +2,7 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Collection; import java.util.List; /** @@ -48,12 +49,12 @@ public static List getStatusHierarchy() { return statusHierarchy; } - public static Status getHighestStatus(List statusList) { + public static Status getHighestStatus(Collection statusCollection) { Status highestStatus = Status.PASS; - if (statusList == null || statusList.isEmpty()) { + if (statusCollection == null || statusCollection.isEmpty()) { return highestStatus; } - for (Status status : statusList) { + for (Status status : statusCollection) { highestStatus = Status.getStatusHierarchy().indexOf(status) < Status.getStatusHierarchy().indexOf(highestStatus) ? status : highestStatus; diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index fd32d6b..67d30ef 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.StringWriter; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -72,7 +73,7 @@ public abstract class BasicFileReporter extends AbstractReporter { private TestAttributeTestContextProvider deviceContext; private SystemAttributeContext systemAttributeContext; private ReportStatusStats stats; - private List statusList; + private Collection statusCollection; protected BasicFileReporter(String path) { this.filePath = path; @@ -164,7 +165,7 @@ public synchronized void flush(ReportAggregates reportAggregates) { this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); this.testList = reportAggregates.getTestList(); this.testRunnerLogs = reportAggregates.getTestRunnerLogs(); - this.statusList = reportAggregates.getStatusList(); + this.statusCollection = reportAggregates.getStatusCollection(); } public List getTestList() { @@ -199,8 +200,8 @@ public ReportStatusStats getReportStatusStats() { return stats; } - public List getStatusList() { - return statusList; + public Collection getStatusCollection() { + return statusCollection; } @Override @@ -288,7 +289,7 @@ public boolean containsStatus(String status) { } public boolean containsStatus(Status status) { - return getStatusList() != null && getStatusList().contains(status); + return getStatusCollection() != null && getStatusCollection().contains(status); } protected void processTemplate(Template template, File outputFile) throws TemplateException, IOException { From 1f3074527197844fe5a3f2679f15bf97527f1754 Mon Sep 17 00:00:00 2001 From: Virender Date: Tue, 2 Apr 2019 22:53:51 +0530 Subject: [PATCH 16/77] Minor corrections: Text edits and removal of unused imports --- .../java/com/aventstack/extentreports/ExtentObservable.java | 6 +----- .../java/com/aventstack/extentreports/ReportAggregates.java | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 1c82a2d..a0b7561 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -4,13 +4,9 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Date; -import java.util.EnumMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; import com.aventstack.extentreports.model.Author; import com.aventstack.extentreports.model.Category; @@ -136,7 +132,7 @@ abstract class ExtentObservable private ReportStatusStats stats = new ReportStatusStats(strategy); /** - * A Set of status tests are marked with + * A unique collection of statuses tests are marked with * *

    * Consider a report having 10 tests: diff --git a/src/main/java/com/aventstack/extentreports/ReportAggregates.java b/src/main/java/com/aventstack/extentreports/ReportAggregates.java index 931de9f..ad15bdc 100644 --- a/src/main/java/com/aventstack/extentreports/ReportAggregates.java +++ b/src/main/java/com/aventstack/extentreports/ReportAggregates.java @@ -3,7 +3,6 @@ import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.Set; import com.aventstack.extentreports.model.Author; import com.aventstack.extentreports.model.Category; From 403ee4c78bfeb8f1f0c7faa32fb24a9f8c9cc84b Mon Sep 17 00:00:00 2001 From: Virender Singh Date: Sun, 14 Apr 2019 19:42:32 +0530 Subject: [PATCH 17/77] Fixing concurrent modification exception when ExtentTest.addlog is called --- .../extentreports/ExtentObservable.java | 2 +- .../api/BddWithStepStatusHierarchyTest.java | 28 +- .../api/NodeSingleLogsStatusTest.java | 11 +- .../api/NodesStatusHierarchyTest.java | 332 +++++++++--------- .../api/TestStartEndDateTimeTest.java | 1 + 5 files changed, 200 insertions(+), 174 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index a0b7561..2b61c6b 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -296,7 +296,7 @@ synchronized void addNode(Test node) { * @param log {@link Log} */ synchronized void addLog(Test test, Log log) { - collectRunInfo(); + //collectRunInfo(); reporterList.forEach(x -> x.onLogAdded(test, log)); } diff --git a/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java b/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java index d42c327..b0a4dc4 100644 --- a/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java +++ b/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java @@ -112,7 +112,8 @@ public void verifySkipHasHigherPriorityThanPassUsingGherkinKeyword(Method method ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").pass("pass"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").skip("skip"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").skip("skip"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.PASS); Assert.assertEquals(and.getStatus(), Status.PASS); Assert.assertEquals(when.getStatus(), Status.PASS); @@ -131,6 +132,7 @@ public void verifySkipHasHigherPriorityThanPassUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").pass("pass"); ExtentTest then = scenario.createNode(Then.class, "Then").skip("skip"); ExtentTest but = scenario.createNode(But.class, "But").skip("skip"); + extent.flush(); Assert.assertEquals(given.getStatus(), Status.PASS); Assert.assertEquals(and.getStatus(), Status.PASS); @@ -150,7 +152,8 @@ public void verifyWarningHasHigherPriorityThanSkipUsingGherkinKeyword(Method met ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").skip("skip"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").warning("warning"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").warning("warning"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.SKIP); Assert.assertEquals(and.getStatus(), Status.SKIP); Assert.assertEquals(when.getStatus(), Status.SKIP); @@ -169,7 +172,8 @@ public void verifyWarningHasHigherPriorityThanSkipUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").skip("skip"); ExtentTest then = scenario.createNode(Then.class, "Then").warning("warning"); ExtentTest but = scenario.createNode(But.class, "But").warning("warning"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.SKIP); Assert.assertEquals(and.getStatus(), Status.SKIP); Assert.assertEquals(when.getStatus(), Status.SKIP); @@ -188,7 +192,8 @@ public void verifyErrorHasHigherPriorityThanWarningUsingGherkinKeyword(Method me ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").warning("warning"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").error("error"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").error("error"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.WARNING); Assert.assertEquals(and.getStatus(), Status.WARNING); Assert.assertEquals(when.getStatus(), Status.WARNING); @@ -207,7 +212,8 @@ public void verifyErrorHasHigherPriorityThanWarningUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").warning("warning"); ExtentTest then = scenario.createNode(Then.class, "Then").error("error"); ExtentTest but = scenario.createNode(But.class, "But").error("error"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.WARNING); Assert.assertEquals(and.getStatus(), Status.WARNING); Assert.assertEquals(when.getStatus(), Status.WARNING); @@ -226,7 +232,8 @@ public void verifyFailHasHigherPriorityThanErrorUsingGherkinKeyword(Method metho ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").error("error"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").fail("fail"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").fail("fail"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.ERROR); Assert.assertEquals(and.getStatus(), Status.ERROR); Assert.assertEquals(when.getStatus(), Status.ERROR); @@ -245,7 +252,8 @@ public void verifyFailHasHigherPriorityThanErrorUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").error("error"); ExtentTest then = scenario.createNode(Then.class, "Then").fail("fail"); ExtentTest but = scenario.createNode(But.class, "But").fail("fail"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.ERROR); Assert.assertEquals(and.getStatus(), Status.ERROR); Assert.assertEquals(when.getStatus(), Status.ERROR); @@ -264,7 +272,8 @@ public void verifyFatalHasHigherPriorityThanFailUsingGherkinKeyword(Method metho ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").fail("fail"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").fatal("fatal"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").fatal("fatal"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.FAIL); Assert.assertEquals(and.getStatus(), Status.FAIL); Assert.assertEquals(when.getStatus(), Status.FAIL); @@ -283,7 +292,8 @@ public void verifyFatalHasHigherPriorityThanFailUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").fail("fail"); ExtentTest then = scenario.createNode(Then.class, "Then").fatal("fatal"); ExtentTest but = scenario.createNode(But.class, "But").fatal("fatal"); - + extent.flush(); + Assert.assertEquals(given.getStatus(), Status.FAIL); Assert.assertEquals(and.getStatus(), Status.FAIL); Assert.assertEquals(when.getStatus(), Status.FAIL); diff --git a/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java b/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java index c549a8c..01a7854 100644 --- a/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java +++ b/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java @@ -26,6 +26,7 @@ public void verifyIfTestHasStatusPass(Method method) { public void verifyIfTestHasStatusSkip(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").skip("skip"); + extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); @@ -37,6 +38,7 @@ public void verifyIfTestHasStatusSkip(Method method) { public void verifyIfTestHasStatusWarning(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").warning("warning"); + extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); @@ -48,7 +50,8 @@ public void verifyIfTestHasStatusWarning(Method method) { public void verifyIfTestHasStatusError(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").error("error"); - + extent.flush(); + Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); Assert.assertEquals(node.getStatus(), Status.ERROR); @@ -59,7 +62,8 @@ public void verifyIfTestHasStatusError(Method method) { public void verifyIfTestHasStatusFail(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").fail("fail"); - + extent.flush(); + Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); Assert.assertEquals(node.getStatus(), Status.FAIL); @@ -70,7 +74,8 @@ public void verifyIfTestHasStatusFail(Method method) { public void verifyIfTestHasStatusFatal(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").fatal("fatal"); - + extent.flush(); + Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); Assert.assertEquals(node.getStatus(), Status.FATAL); diff --git a/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java b/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java index 4b82354..2b5973f 100644 --- a/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java +++ b/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java @@ -11,165 +11,175 @@ public class NodesStatusHierarchyTest extends Base { - @Test - public void verifyPassHasHigherPriorityThanInfoLevelsShallow(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - child.info("info"); - child.pass("pass"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(parent.getStatus(), Status.PASS); - Assert.assertEquals(child.getStatus(), Status.PASS); - } - - @Test - public void verifyPassHasHigherPriorityThanInfoLevelsDeep(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - ExtentTest grandchild = child.createNode("GrandChild"); - grandchild.info("info"); - grandchild.pass("pass"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(grandchild.getModel().getLevel(), 2); - Assert.assertEquals(parent.getStatus(), Status.PASS); - Assert.assertEquals(child.getStatus(), Status.PASS); - Assert.assertEquals(grandchild.getStatus(), Status.PASS); - } - - @Test - public void verifySkipHasHigherPriorityThanPassLevelsShallow(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - child.pass("pass"); - child.skip("skip"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(parent.getStatus(), Status.SKIP); - Assert.assertEquals(child.getStatus(), Status.SKIP); - } - - @Test - public void verifySkipHasHigherPriorityThanPassLevelsDeep(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - ExtentTest grandchild = child.createNode("GrandChild"); - grandchild.pass("pass"); - grandchild.skip("skip"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(grandchild.getModel().getLevel(), 2); - Assert.assertEquals(parent.getStatus(), Status.SKIP); - Assert.assertEquals(child.getStatus(), Status.SKIP); - Assert.assertEquals(grandchild.getStatus(), Status.SKIP); - } - - @Test - public void verifyWarningHasHigherPriorityThanSkipLevelsShallow(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - child.skip("skip"); - child.warning("warning"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(parent.getStatus(), Status.WARNING); - Assert.assertEquals(child.getStatus(), Status.WARNING); - } - - @Test - public void verifyWarningHasHigherPriorityThanSkipLevelsDeep(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - ExtentTest grandchild = child.createNode("GrandChild"); - grandchild.skip("skip"); - grandchild.warning("warning"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(grandchild.getModel().getLevel(), 2); - Assert.assertEquals(parent.getStatus(), Status.WARNING); - Assert.assertEquals(child.getStatus(), Status.WARNING); - Assert.assertEquals(grandchild.getStatus(), Status.WARNING); - } - - @Test - public void verifyErrorHasHigherPriorityThanWarningLevelsShallow(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - child.warning("warning"); - child.error("error"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(parent.getStatus(), Status.ERROR); - Assert.assertEquals(child.getStatus(), Status.ERROR); - } - - @Test - public void verifyErrorHasHigherPriorityThanWarningLevelsDeep(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - ExtentTest grandchild = child.createNode("GrandChild"); - grandchild.warning("warning"); - grandchild.error("error"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(grandchild.getModel().getLevel(), 2); - Assert.assertEquals(parent.getStatus(), Status.ERROR); - Assert.assertEquals(child.getStatus(), Status.ERROR); - Assert.assertEquals(grandchild.getStatus(), Status.ERROR); - } - - @Test - public void verifFailHasHigherPriorityThanErrorLevelsShallow(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - child.error("error"); - child.fail("fail"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(parent.getStatus(), Status.FAIL); - Assert.assertEquals(child.getStatus(), Status.FAIL); - } - - @Test - public void verifFailHasHigherPriorityThanErrorLevelsDeep(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - ExtentTest grandchild = child.createNode("GrandChild"); - grandchild.error("error"); - grandchild.fail("fail"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(grandchild.getModel().getLevel(), 2); - Assert.assertEquals(parent.getStatus(), Status.FAIL); - Assert.assertEquals(child.getStatus(), Status.FAIL); - Assert.assertEquals(grandchild.getStatus(), Status.FAIL); - } - - @Test - public void verifFatalHasHigherPriorityThanFailLevelsShallow(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - child.fail("fail"); - child.fatal("fatal"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(parent.getStatus(), Status.FATAL); - Assert.assertEquals(child.getStatus(), Status.FATAL); - } - - @Test - public void verifFatalHasHigherPriorityThanFailLevelsDeep(Method method) { - ExtentTest parent = extent.createTest(method.getName()); - ExtentTest child = parent.createNode("Child"); - ExtentTest grandchild = child.createNode("GrandChild"); - grandchild.fail("fail"); - grandchild.fatal("fatal"); - - Assert.assertEquals(child.getModel().getLevel(), 1); - Assert.assertEquals(grandchild.getModel().getLevel(), 2); - Assert.assertEquals(parent.getStatus(), Status.FATAL); - Assert.assertEquals(child.getStatus(), Status.FATAL); - Assert.assertEquals(grandchild.getStatus(), Status.FATAL); - } + @Test + public void verifyPassHasHigherPriorityThanInfoLevelsShallow(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + child.info("info"); + child.pass("pass"); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(parent.getStatus(), Status.PASS); + Assert.assertEquals(child.getStatus(), Status.PASS); + } + + @Test + public void verifyPassHasHigherPriorityThanInfoLevelsDeep(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + ExtentTest grandchild = child.createNode("GrandChild"); + grandchild.info("info"); + grandchild.pass("pass"); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(grandchild.getModel().getLevel(), 2); + Assert.assertEquals(parent.getStatus(), Status.PASS); + Assert.assertEquals(child.getStatus(), Status.PASS); + Assert.assertEquals(grandchild.getStatus(), Status.PASS); + } + + @Test + public void verifySkipHasHigherPriorityThanPassLevelsShallow(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + child.pass("pass"); + child.skip("skip"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(parent.getStatus(), Status.SKIP); + Assert.assertEquals(child.getStatus(), Status.SKIP); + } + + @Test + public void verifySkipHasHigherPriorityThanPassLevelsDeep(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + ExtentTest grandchild = child.createNode("GrandChild"); + grandchild.pass("pass"); + grandchild.skip("skip"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(grandchild.getModel().getLevel(), 2); + Assert.assertEquals(parent.getStatus(), Status.SKIP); + Assert.assertEquals(child.getStatus(), Status.SKIP); + Assert.assertEquals(grandchild.getStatus(), Status.SKIP); + } + + @Test + public void verifyWarningHasHigherPriorityThanSkipLevelsShallow(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + child.skip("skip"); + child.warning("warning"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(parent.getStatus(), Status.WARNING); + Assert.assertEquals(child.getStatus(), Status.WARNING); + } + + @Test + public void verifyWarningHasHigherPriorityThanSkipLevelsDeep(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + ExtentTest grandchild = child.createNode("GrandChild"); + grandchild.skip("skip"); + grandchild.warning("warning"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(grandchild.getModel().getLevel(), 2); + Assert.assertEquals(parent.getStatus(), Status.WARNING); + Assert.assertEquals(child.getStatus(), Status.WARNING); + Assert.assertEquals(grandchild.getStatus(), Status.WARNING); + } + + @Test + public void verifyErrorHasHigherPriorityThanWarningLevelsShallow(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + child.warning("warning"); + child.error("error"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(parent.getStatus(), Status.ERROR); + Assert.assertEquals(child.getStatus(), Status.ERROR); + } + + @Test + public void verifyErrorHasHigherPriorityThanWarningLevelsDeep(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + ExtentTest grandchild = child.createNode("GrandChild"); + grandchild.warning("warning"); + grandchild.error("error"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(grandchild.getModel().getLevel(), 2); + Assert.assertEquals(parent.getStatus(), Status.ERROR); + Assert.assertEquals(child.getStatus(), Status.ERROR); + Assert.assertEquals(grandchild.getStatus(), Status.ERROR); + } + + @Test + public void verifFailHasHigherPriorityThanErrorLevelsShallow(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + child.error("error"); + child.fail("fail"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(parent.getStatus(), Status.FAIL); + Assert.assertEquals(child.getStatus(), Status.FAIL); + } + + @Test + public void verifFailHasHigherPriorityThanErrorLevelsDeep(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + ExtentTest grandchild = child.createNode("GrandChild"); + grandchild.error("error"); + grandchild.fail("fail"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(grandchild.getModel().getLevel(), 2); + Assert.assertEquals(parent.getStatus(), Status.FAIL); + Assert.assertEquals(child.getStatus(), Status.FAIL); + Assert.assertEquals(grandchild.getStatus(), Status.FAIL); + } + + @Test + public void verifFatalHasHigherPriorityThanFailLevelsShallow(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + child.fail("fail"); + child.fatal("fatal"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(parent.getStatus(), Status.FATAL); + Assert.assertEquals(child.getStatus(), Status.FATAL); + } + + @Test + public void verifFatalHasHigherPriorityThanFailLevelsDeep(Method method) { + ExtentTest parent = extent.createTest(method.getName()); + ExtentTest child = parent.createNode("Child"); + ExtentTest grandchild = child.createNode("GrandChild"); + grandchild.fail("fail"); + grandchild.fatal("fatal"); + extent.flush(); + + Assert.assertEquals(child.getModel().getLevel(), 1); + Assert.assertEquals(grandchild.getModel().getLevel(), 2); + Assert.assertEquals(parent.getStatus(), Status.FATAL); + Assert.assertEquals(child.getStatus(), Status.FATAL); + Assert.assertEquals(grandchild.getStatus(), Status.FATAL); + } } diff --git a/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java b/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java index 83d9c43..11c63af 100644 --- a/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java +++ b/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java @@ -51,6 +51,7 @@ public void testEndTimeNodeTimeTaken(Method method) throws InterruptedException ExtentTest node = test.createNode(method.getName()); Thread.sleep(wait); node.pass("pass"); + extent.flush(); Assert.assertTrue(test.getModel().getEndTime().getTime() >= (init.getTime() + wait)); } From 4f6d816634c34b88f1db344382e52a952172afdb Mon Sep 17 00:00:00 2001 From: Virender Singh Date: Sun, 14 Apr 2019 19:58:58 +0530 Subject: [PATCH 18/77] Removing commented code --- src/main/java/com/aventstack/extentreports/ExtentObservable.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 2b61c6b..699c01d 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -296,7 +296,6 @@ synchronized void addNode(Test node) { * @param log {@link Log} */ synchronized void addLog(Test test, Log log) { - //collectRunInfo(); reporterList.forEach(x -> x.onLogAdded(test, log)); } From 62c8bb93a3fa022888007ef767b41ddc3b9f6621 Mon Sep 17 00:00:00 2001 From: Virender Date: Mon, 15 Apr 2019 23:16:29 +0530 Subject: [PATCH 19/77] Adding the first version of conrtibution guidelines --- Contribution.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Contribution.md diff --git a/Contribution.md b/Contribution.md new file mode 100644 index 0000000..f3f8920 --- /dev/null +++ b/Contribution.md @@ -0,0 +1,49 @@ +#Reporting a Bug# + +The way you report a bug is the most critical part for a quick resolution. Bugs which lack clear description and steps to reproduce are often not fixed. If you find a bug please make sure that you log the bug based on the template below. Make sure that you are as descriptive as possible. + +##Bug Template## + +###Title: Line of text which summarizes what the bug is about. (Max 70 characters)### + +- Be short and precise +- Use simple language and grammar +- Summarize what the issue is and nothing else + +###Description: Describe the issue in a few lines using simple words### + +While describing a bug consider that you are describing it to someone who knows nothing about your problem. Be as elaborate as possible but avoid being verbose. Being verbose here would mean. +- Providing unnecessary details without which the bug can still be described. + +In most of the cases, try to understand the bug in such a way that you can separate program can be written just to reproduce the issue. If you are not able to understand the bug at this moment, just try to recreate the problem with simplest possible code. + +###Things to include in the Description### +- What went wrong? for e.g. Adding a long description to a test results in truncation of the text. +- When it went wrong? for e.g. If you add a text description which is greater than 255 characters, the description text gets truncated + +Things to NOT include in the Description +- You application specific details. For example, do not give elaborate background on what your application does. +- Talking about functions/code which is very specific to your project. We would not know about that. + +###Steps to Reproduce:### +- Detailed and precise steps to reproduce the bugs. +- Make sure that preconditions are specified. For e.g. include a particular library or tool which is necessary to reproduce the scenario. +- If possible you can attach images with annotations explaining where the problem is. +- If possible create a piece of code which can reproduce the issue without having any of your application/framework code. + +###Expected Results### +In the end make sure that you clearly explain what were you expecting. Being very clear here is the key. + + +#What happens after you have logged the bug?# + +We look at bugs periodically. As this is an open source project, we invest time based on the availability. You can expect a reply within 2 - 3 days. If you donot get a reply, please add any of the contributors in the list. + +You can also raise a PR if you know the fix. PR's are always welcome. Please see the code contribution guidelines below. + + + + + + + From 302d25b7b5ffc5e82b8472f46eb91c3a0e979cfe Mon Sep 17 00:00:00 2001 From: Virender Date: Mon, 15 Apr 2019 23:21:51 +0530 Subject: [PATCH 20/77] Renaming the contribution file to contributing --- Contribution.md => Contributing.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Contribution.md => Contributing.md (100%) diff --git a/Contribution.md b/Contributing.md similarity index 100% rename from Contribution.md rename to Contributing.md From 554611b9faaf765c74002ef7a6503d306604e927 Mon Sep 17 00:00:00 2001 From: Virender Date: Mon, 15 Apr 2019 23:27:06 +0530 Subject: [PATCH 21/77] Eclipse markups are not visible on github, changing the markups --- Contributing.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Contributing.md b/Contributing.md index f3f8920..dc3f7fd 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,23 +1,23 @@ -#Reporting a Bug# +#Reporting a Bug The way you report a bug is the most critical part for a quick resolution. Bugs which lack clear description and steps to reproduce are often not fixed. If you find a bug please make sure that you log the bug based on the template below. Make sure that you are as descriptive as possible. -##Bug Template## +##Bug Template -###Title: Line of text which summarizes what the bug is about. (Max 70 characters)### +###Title: Line of text which summarizes what the bug is about. (Max 70 characters) - Be short and precise - Use simple language and grammar - Summarize what the issue is and nothing else -###Description: Describe the issue in a few lines using simple words### +###Description: Describe the issue in a few lines using simple words While describing a bug consider that you are describing it to someone who knows nothing about your problem. Be as elaborate as possible but avoid being verbose. Being verbose here would mean. - Providing unnecessary details without which the bug can still be described. In most of the cases, try to understand the bug in such a way that you can separate program can be written just to reproduce the issue. If you are not able to understand the bug at this moment, just try to recreate the problem with simplest possible code. -###Things to include in the Description### +###Things to include in the Description - What went wrong? for e.g. Adding a long description to a test results in truncation of the text. - When it went wrong? for e.g. If you add a text description which is greater than 255 characters, the description text gets truncated @@ -25,17 +25,17 @@ Things to NOT include in the Description - You application specific details. For example, do not give elaborate background on what your application does. - Talking about functions/code which is very specific to your project. We would not know about that. -###Steps to Reproduce:### +###Steps to Reproduce: - Detailed and precise steps to reproduce the bugs. - Make sure that preconditions are specified. For e.g. include a particular library or tool which is necessary to reproduce the scenario. - If possible you can attach images with annotations explaining where the problem is. - If possible create a piece of code which can reproduce the issue without having any of your application/framework code. -###Expected Results### +###Expected Results In the end make sure that you clearly explain what were you expecting. Being very clear here is the key. -#What happens after you have logged the bug?# +#What happens after you have logged the bug? We look at bugs periodically. As this is an open source project, we invest time based on the availability. You can expect a reply within 2 - 3 days. If you donot get a reply, please add any of the contributors in the list. From 2b0b9a9c0ef4413c4da88d87e21567c477d89afd Mon Sep 17 00:00:00 2001 From: Virender Date: Mon, 15 Apr 2019 23:30:36 +0530 Subject: [PATCH 22/77] Removing unexpected characters from the contribution file --- Contributing.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Contributing.md b/Contributing.md index dc3f7fd..32c2428 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,23 +1,23 @@ -#Reporting a Bug +# Reporting a Bug The way you report a bug is the most critical part for a quick resolution. Bugs which lack clear description and steps to reproduce are often not fixed. If you find a bug please make sure that you log the bug based on the template below. Make sure that you are as descriptive as possible. -##Bug Template +## Bug Template -###Title: Line of text which summarizes what the bug is about. (Max 70 characters) +### Title: Line of text which summarizes what the bug is about. (Max 70 characters) - Be short and precise - Use simple language and grammar - Summarize what the issue is and nothing else -###Description: Describe the issue in a few lines using simple words +### Description: Describe the issue in a few lines using simple words While describing a bug consider that you are describing it to someone who knows nothing about your problem. Be as elaborate as possible but avoid being verbose. Being verbose here would mean. - Providing unnecessary details without which the bug can still be described. In most of the cases, try to understand the bug in such a way that you can separate program can be written just to reproduce the issue. If you are not able to understand the bug at this moment, just try to recreate the problem with simplest possible code. -###Things to include in the Description +### Things to include in the Description - What went wrong? for e.g. Adding a long description to a test results in truncation of the text. - When it went wrong? for e.g. If you add a text description which is greater than 255 characters, the description text gets truncated @@ -25,17 +25,17 @@ Things to NOT include in the Description - You application specific details. For example, do not give elaborate background on what your application does. - Talking about functions/code which is very specific to your project. We would not know about that. -###Steps to Reproduce: +### Steps to Reproduce: - Detailed and precise steps to reproduce the bugs. - Make sure that preconditions are specified. For e.g. include a particular library or tool which is necessary to reproduce the scenario. - If possible you can attach images with annotations explaining where the problem is. - If possible create a piece of code which can reproduce the issue without having any of your application/framework code. -###Expected Results +### Expected Results In the end make sure that you clearly explain what were you expecting. Being very clear here is the key. -#What happens after you have logged the bug? +# What happens after you have logged the bug? We look at bugs periodically. As this is an open source project, we invest time based on the availability. You can expect a reply within 2 - 3 days. If you donot get a reply, please add any of the contributors in the list. From 43baa5bb2fb2bf781ffee31278cffae2edcd15f4 Mon Sep 17 00:00:00 2001 From: Virender Singh Date: Fri, 26 Apr 2019 08:35:18 +0530 Subject: [PATCH 23/77] Adding flush when we need to get the current status of the report --- .../extentreports/ExtentObservable.java | 1 + .../com/aventstack/extentreports/ExtentTest.java | 15 +++++++++++++++ .../reporter/ExtentHtmlReporter.java | 2 +- .../api/BddWithStepStatusHierarchyTest.java | 13 +++---------- .../api/NodeSingleLogsStatusTest.java | 5 ----- .../api/NodesStatusHierarchyTest.java | 10 ---------- .../api/TestStartEndDateTimeTest.java | 3 +-- 7 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 699c01d..251f318 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -594,6 +594,7 @@ protected boolean getAllowManualConfig() { * @return a {@link ReportStatusStats} object */ protected ReportStatusStats getStats() { + flush(); return stats; } diff --git a/src/main/java/com/aventstack/extentreports/ExtentTest.java b/src/main/java/com/aventstack/extentreports/ExtentTest.java index a36e634..5c05a7b 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentTest.java +++ b/src/main/java/com/aventstack/extentreports/ExtentTest.java @@ -1190,6 +1190,21 @@ public ExtentTest addScreencastFromPath(String screencastPath) throws IOExceptio * @return {@link Status} */ public Status getStatus() { + /* + * Flushing the report here seems counter intuitive. However, + * the status of the report is not updated till we get a + * call to read something the current status of the report. + * This allows us to delay the work which we would have done + * on every update to the status. + * @viren: Think of a better design to store and update the status + * + * For the time being we will resort to flush here as it still + * avoid the additional work we used to do with every log addition + * and it also minimizes the risk of getting Concurrent modification + * error. + * Done as part of: pull request #75 + */ + extent.flush(); return getModel().getStatus(); } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java index 0c005c5..788c4dd 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java @@ -10,7 +10,7 @@ import freemarker.template.Template; import freemarker.template.TemplateException; - + /** * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several * configuration options via the config() method. diff --git a/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java b/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java index b0a4dc4..4ce8280 100644 --- a/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java +++ b/src/test/java/com/aventstack/extentreports/api/BddWithStepStatusHierarchyTest.java @@ -112,7 +112,6 @@ public void verifySkipHasHigherPriorityThanPassUsingGherkinKeyword(Method method ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").pass("pass"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").skip("skip"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").skip("skip"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.PASS); Assert.assertEquals(and.getStatus(), Status.PASS); @@ -132,7 +131,7 @@ public void verifySkipHasHigherPriorityThanPassUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").pass("pass"); ExtentTest then = scenario.createNode(Then.class, "Then").skip("skip"); ExtentTest but = scenario.createNode(But.class, "But").skip("skip"); - extent.flush(); + // Assert.assertEquals(given.getStatus(), Status.PASS); Assert.assertEquals(and.getStatus(), Status.PASS); @@ -152,7 +151,6 @@ public void verifyWarningHasHigherPriorityThanSkipUsingGherkinKeyword(Method met ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").skip("skip"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").warning("warning"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").warning("warning"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.SKIP); Assert.assertEquals(and.getStatus(), Status.SKIP); @@ -172,7 +170,6 @@ public void verifyWarningHasHigherPriorityThanSkipUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").skip("skip"); ExtentTest then = scenario.createNode(Then.class, "Then").warning("warning"); ExtentTest but = scenario.createNode(But.class, "But").warning("warning"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.SKIP); Assert.assertEquals(and.getStatus(), Status.SKIP); @@ -192,7 +189,7 @@ public void verifyErrorHasHigherPriorityThanWarningUsingGherkinKeyword(Method me ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").warning("warning"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").error("error"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").error("error"); - extent.flush(); + Assert.assertEquals(given.getStatus(), Status.WARNING); Assert.assertEquals(and.getStatus(), Status.WARNING); @@ -212,7 +209,6 @@ public void verifyErrorHasHigherPriorityThanWarningUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").warning("warning"); ExtentTest then = scenario.createNode(Then.class, "Then").error("error"); ExtentTest but = scenario.createNode(But.class, "But").error("error"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.WARNING); Assert.assertEquals(and.getStatus(), Status.WARNING); @@ -232,7 +228,6 @@ public void verifyFailHasHigherPriorityThanErrorUsingGherkinKeyword(Method metho ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").error("error"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").fail("fail"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").fail("fail"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.ERROR); Assert.assertEquals(and.getStatus(), Status.ERROR); @@ -252,7 +247,7 @@ public void verifyFailHasHigherPriorityThanErrorUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").error("error"); ExtentTest then = scenario.createNode(Then.class, "Then").fail("fail"); ExtentTest but = scenario.createNode(But.class, "But").fail("fail"); - extent.flush(); + Assert.assertEquals(given.getStatus(), Status.ERROR); Assert.assertEquals(and.getStatus(), Status.ERROR); @@ -272,7 +267,6 @@ public void verifyFatalHasHigherPriorityThanFailUsingGherkinKeyword(Method metho ExtentTest when = scenario.createNode(new GherkinKeyword("When"), "When").fail("fail"); ExtentTest then = scenario.createNode(new GherkinKeyword("Then"), "Then").fatal("fatal"); ExtentTest but = scenario.createNode(new GherkinKeyword("But"), "But").fatal("fatal"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.FAIL); Assert.assertEquals(and.getStatus(), Status.FAIL); @@ -292,7 +286,6 @@ public void verifyFatalHasHigherPriorityThanFailUsingClass(Method method) { ExtentTest when = scenario.createNode(When.class, "When").fail("fail"); ExtentTest then = scenario.createNode(Then.class, "Then").fatal("fatal"); ExtentTest but = scenario.createNode(But.class, "But").fatal("fatal"); - extent.flush(); Assert.assertEquals(given.getStatus(), Status.FAIL); Assert.assertEquals(and.getStatus(), Status.FAIL); diff --git a/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java b/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java index 01a7854..a7f34b1 100644 --- a/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java +++ b/src/test/java/com/aventstack/extentreports/api/NodeSingleLogsStatusTest.java @@ -26,7 +26,6 @@ public void verifyIfTestHasStatusPass(Method method) { public void verifyIfTestHasStatusSkip(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").skip("skip"); - extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); @@ -38,7 +37,6 @@ public void verifyIfTestHasStatusSkip(Method method) { public void verifyIfTestHasStatusWarning(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").warning("warning"); - extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); @@ -50,7 +48,6 @@ public void verifyIfTestHasStatusWarning(Method method) { public void verifyIfTestHasStatusError(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").error("error"); - extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); @@ -62,7 +59,6 @@ public void verifyIfTestHasStatusError(Method method) { public void verifyIfTestHasStatusFail(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").fail("fail"); - extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); @@ -74,7 +70,6 @@ public void verifyIfTestHasStatusFail(Method method) { public void verifyIfTestHasStatusFatal(Method method) { ExtentTest test = extent.createTest(method.getName()); ExtentTest node = test.createNode("Child").fatal("fatal"); - extent.flush(); Assert.assertEquals(node.getModel().getLevel(), 1); Assert.assertEquals(node.getModel().getLogContext().size(), 1); diff --git a/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java b/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java index 2b5973f..6f65fb9 100644 --- a/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java +++ b/src/test/java/com/aventstack/extentreports/api/NodesStatusHierarchyTest.java @@ -44,7 +44,6 @@ public void verifySkipHasHigherPriorityThanPassLevelsShallow(Method method) { ExtentTest child = parent.createNode("Child"); child.pass("pass"); child.skip("skip"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(parent.getStatus(), Status.SKIP); @@ -58,7 +57,6 @@ public void verifySkipHasHigherPriorityThanPassLevelsDeep(Method method) { ExtentTest grandchild = child.createNode("GrandChild"); grandchild.pass("pass"); grandchild.skip("skip"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(grandchild.getModel().getLevel(), 2); @@ -73,7 +71,6 @@ public void verifyWarningHasHigherPriorityThanSkipLevelsShallow(Method method) { ExtentTest child = parent.createNode("Child"); child.skip("skip"); child.warning("warning"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(parent.getStatus(), Status.WARNING); @@ -87,7 +84,6 @@ public void verifyWarningHasHigherPriorityThanSkipLevelsDeep(Method method) { ExtentTest grandchild = child.createNode("GrandChild"); grandchild.skip("skip"); grandchild.warning("warning"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(grandchild.getModel().getLevel(), 2); @@ -102,7 +98,6 @@ public void verifyErrorHasHigherPriorityThanWarningLevelsShallow(Method method) ExtentTest child = parent.createNode("Child"); child.warning("warning"); child.error("error"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(parent.getStatus(), Status.ERROR); @@ -116,7 +111,6 @@ public void verifyErrorHasHigherPriorityThanWarningLevelsDeep(Method method) { ExtentTest grandchild = child.createNode("GrandChild"); grandchild.warning("warning"); grandchild.error("error"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(grandchild.getModel().getLevel(), 2); @@ -131,7 +125,6 @@ public void verifFailHasHigherPriorityThanErrorLevelsShallow(Method method) { ExtentTest child = parent.createNode("Child"); child.error("error"); child.fail("fail"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(parent.getStatus(), Status.FAIL); @@ -145,7 +138,6 @@ public void verifFailHasHigherPriorityThanErrorLevelsDeep(Method method) { ExtentTest grandchild = child.createNode("GrandChild"); grandchild.error("error"); grandchild.fail("fail"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(grandchild.getModel().getLevel(), 2); @@ -160,7 +152,6 @@ public void verifFatalHasHigherPriorityThanFailLevelsShallow(Method method) { ExtentTest child = parent.createNode("Child"); child.fail("fail"); child.fatal("fatal"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(parent.getStatus(), Status.FATAL); @@ -174,7 +165,6 @@ public void verifFatalHasHigherPriorityThanFailLevelsDeep(Method method) { ExtentTest grandchild = child.createNode("GrandChild"); grandchild.fail("fail"); grandchild.fatal("fatal"); - extent.flush(); Assert.assertEquals(child.getModel().getLevel(), 1); Assert.assertEquals(grandchild.getModel().getLevel(), 2); diff --git a/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java b/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java index 11c63af..cd1a90d 100644 --- a/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java +++ b/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java @@ -51,8 +51,7 @@ public void testEndTimeNodeTimeTaken(Method method) throws InterruptedException ExtentTest node = test.createNode(method.getName()); Thread.sleep(wait); node.pass("pass"); - extent.flush(); - + test.getModel().end(); Assert.assertTrue(test.getModel().getEndTime().getTime() >= (init.getTime() + wait)); } From 6c2f75339c7a93e0161f9b05406bffe1863d9005 Mon Sep 17 00:00:00 2001 From: Virender Date: Wed, 8 May 2019 00:14:54 +0530 Subject: [PATCH 24/77] Added a new public method to explicit update the report status as opposed to doing it every time. Used this method to keep the report status in sync. --- .../extentreports/ExtentObservable.java | 15 ++++++++++++++- .../aventstack/extentreports/ExtentTest.java | 17 +---------------- .../aventstack/extentreports/ReportService.java | 3 ++- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 251f318..58ece6b 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -594,8 +594,21 @@ protected boolean getAllowManualConfig() { * @return a {@link ReportStatusStats} object */ protected ReportStatusStats getStats() { - flush(); + generateRecentStatus(); return stats; } + /** + * Calculates the current status of the report and + * updates the internal status. After using this we + * + * Note: Internal methods to get status like + * - ExtentTest.getStatus + * - ExtentReport.getStatus + * call this method to calculate the most recent status + * before returning the status. + */ + public void generateRecentStatus() { + collectRunInfo(); + } } diff --git a/src/main/java/com/aventstack/extentreports/ExtentTest.java b/src/main/java/com/aventstack/extentreports/ExtentTest.java index 5c05a7b..fa76009 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentTest.java +++ b/src/main/java/com/aventstack/extentreports/ExtentTest.java @@ -1190,21 +1190,7 @@ public ExtentTest addScreencastFromPath(String screencastPath) throws IOExceptio * @return {@link Status} */ public Status getStatus() { - /* - * Flushing the report here seems counter intuitive. However, - * the status of the report is not updated till we get a - * call to read something the current status of the report. - * This allows us to delay the work which we would have done - * on every update to the status. - * @viren: Think of a better design to store and update the status - * - * For the time being we will resort to flush here as it still - * avoid the additional work we used to do with every log addition - * and it also minimizes the risk of getting Concurrent modification - * error. - * Done as part of: pull request #75 - */ - extent.flush(); + extent.generateRecentStatus(); return getModel().getStatus(); } @@ -1229,5 +1215,4 @@ public ExtentReports getExtent() { void setUseManualConfiguration(Boolean b) { getModel().setUseManualConfiguration(b); } - } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportService.java b/src/main/java/com/aventstack/extentreports/ReportService.java index 4fdfde2..048e690 100644 --- a/src/main/java/com/aventstack/extentreports/ReportService.java +++ b/src/main/java/com/aventstack/extentreports/ReportService.java @@ -8,6 +8,7 @@ */ public interface ReportService { - void attachReporter(ExtentReporter... reporter); + void attachReporter(ExtentReporter... reporter); + void generateRecentStatus(); } From 54e0bafe12f8244cd2a0981fc55c4d238d101e59 Mon Sep 17 00:00:00 2001 From: Virender Date: Wed, 8 May 2019 08:40:33 +0530 Subject: [PATCH 25/77] Renaming collectRunInfo to generateRecentStatus to expose it publically --- .../extentreports/ExtentObservable.java | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 58ece6b..9948e37 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -414,7 +414,7 @@ private void endTest(Test test) { * */ protected synchronized void flush() { - collectRunInfo(); + generateRecentStatus(); notifyReporters(); } @@ -423,7 +423,7 @@ protected synchronized void flush() { * Exception, Nodes. This also ends and updates all internal test information and * refreshes {@link ReportStatusStats} and the distinct list of {@link Status} */ - private synchronized void collectRunInfo() { + public synchronized void generateRecentStatus() { if (testList == null || testList.isEmpty()) return; @@ -597,18 +597,4 @@ protected ReportStatusStats getStats() { generateRecentStatus(); return stats; } - - /** - * Calculates the current status of the report and - * updates the internal status. After using this we - * - * Note: Internal methods to get status like - * - ExtentTest.getStatus - * - ExtentReport.getStatus - * call this method to calculate the most recent status - * before returning the status. - */ - public void generateRecentStatus() { - collectRunInfo(); - } } From 85f61b503ebb385dcfeac5aecc49fa9feae9e896 Mon Sep 17 00:00:00 2001 From: Virender Date: Sat, 11 May 2019 22:43:51 +0530 Subject: [PATCH 26/77] Simplifying the recursion of function Test.updateTestStatusRecursive and changing the name of the method Test.getNodeContext to meaningful Test.getChildrenNodes --- .../extentreports/ExtentObservable.java | 6 +-- .../aventstack/extentreports/ExtentTest.java | 2 +- .../extentreports/ReportStatusStats.java | 14 +++---- .../aventstack/extentreports/TestRemover.java | 2 +- .../aventstack/extentreports/model/Test.java | 42 +++++++------------ .../reporter/ExtentKlovReporter.java | 10 ++--- .../api/TestInitializeNullValuesTest.java | 4 +- .../api/TestStartEndDateTimeTest.java | 4 +- .../extentreports/model/TestModelTest.java | 18 ++++---- 9 files changed, 45 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java index 9948e37..9e5d339 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ b/src/main/java/com/aventstack/extentreports/ExtentObservable.java @@ -277,7 +277,7 @@ private synchronized void refreshStatusList(List list) { return; list.forEach(x -> statusSet.add(x.getStatus())); - list.forEach(x -> refreshStatusList(x.getNodeContext().getAll())); + list.forEach(x -> refreshStatusList(x.getChildrenNodes().getAll())); } /** @@ -451,7 +451,7 @@ public synchronized void generateRecentStatus() { .forEach(x -> exceptionContextBuilder.setExceptionContext(x, test)); } if (test.hasChildren()) { - for (Test node : test.getNodeContext().getAll()) { + for (Test node : test.getChildrenNodes().getAll()) { copyNodeAttributeAndRunTimeInfoToAttributeContexts(node); node.setUseManualConfiguration(getAllowManualConfig()); } @@ -504,7 +504,7 @@ private void copyNodeAttributeAndRunTimeInfoToAttributeContexts(Test node) { .forEach(x -> exceptionContextBuilder.setExceptionContext(x, node)); } if (node.hasChildren()) { - node.getNodeContext().getAll() + node.getChildrenNodes().getAll() .forEach(this::copyNodeAttributeAndRunTimeInfoToAttributeContexts); } } diff --git a/src/main/java/com/aventstack/extentreports/ExtentTest.java b/src/main/java/com/aventstack/extentreports/ExtentTest.java index fa76009..7696a42 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentTest.java +++ b/src/main/java/com/aventstack/extentreports/ExtentTest.java @@ -277,7 +277,7 @@ public synchronized ExtentTest createNode(String name) { private void applyCommonNodeSettings(ExtentTest extentTest) { extentTest.getModel().setLevel(test.getLevel() + 1); extentTest.getModel().setParent(getModel()); - test.getNodeContext().add(extentTest.getModel()); + test.addChildNode(extentTest.getModel()); } private void addNodeToReport(ExtentTest extentNode) { diff --git a/src/main/java/com/aventstack/extentreports/ReportStatusStats.java b/src/main/java/com/aventstack/extentreports/ReportStatusStats.java index 5236617..017dd2c 100644 --- a/src/main/java/com/aventstack/extentreports/ReportStatusStats.java +++ b/src/main/java/com/aventstack/extentreports/ReportStatusStats.java @@ -192,7 +192,7 @@ private void refreshStats() { } private void addTestForStatusStatsUpdate(Test test) { - if (test.isBehaviorDrivenType() || (test.hasChildren() && test.getNodeContext().get(0).isBehaviorDrivenType())) { + if (test.isBehaviorDrivenType() || (test.hasChildren() && test.getChildrenNodes().get(0).isBehaviorDrivenType())) { updateGroupCountsBDD(test); return; } @@ -214,11 +214,11 @@ private void updateGroupCountsSuiteStrategy(Test test) { incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); if (test.hasChildren()) { - test.getNodeContext().getAll().forEach(x -> { + test.getChildrenNodes().getAll().forEach(x -> { incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); if (x.hasChildren()) - x.getNodeContext().getAll().forEach(n -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus())); + x.getChildrenNodes().getAll().forEach(n -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus())); }); } } @@ -227,16 +227,16 @@ private void updateGroupCountsBDD(Test test) { incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); if (test.hasChildren()) { - test.getNodeContext().getAll().forEach(x -> { + test.getChildrenNodes().getAll().forEach(x -> { if (x.getBehaviorDrivenType() == Scenario.class) incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); if (x.hasChildren()) { - x.getNodeContext().getAll().forEach(n -> { + x.getChildrenNodes().getAll().forEach(n -> { if (n.getBehaviorDrivenType() == Scenario.class) { incrementItemCountByStatus(ItemLevel.CHILD, n.getStatus()); - n.getNodeContext().getAll().forEach(z -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, z.getStatus())); + n.getChildrenNodes().getAll().forEach(z -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, z.getStatus())); } else { incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus()); @@ -256,7 +256,7 @@ private void updateGroupCountsTestStrategy(Test test) { } private void updateGroupCountsTestStrategyChildren(Test test) { - test.getNodeContext().getAll().forEach(x -> { + test.getChildrenNodes().getAll().forEach(x -> { if (!x.hasChildren()) { incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); } else { diff --git a/src/main/java/com/aventstack/extentreports/TestRemover.java b/src/main/java/com/aventstack/extentreports/TestRemover.java index 296c70c..09a310e 100644 --- a/src/main/java/com/aventstack/extentreports/TestRemover.java +++ b/src/main/java/com/aventstack/extentreports/TestRemover.java @@ -50,7 +50,7 @@ private static void findAndRemoveTest(List list, Test test) { if (removed) { return; } - findAndRemoveTest(t.getNodeContext().getAll(), test); + findAndRemoveTest(t.getChildrenNodes().getAll(), test); } } diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index 7d4cda5..7271f0f 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -184,14 +184,13 @@ public void setLevel(int level) { this.level = level; } - public void setParent(Test parent) { this.parent = parent; } public Test getParent() { return parent; } - public AbstractStructure getNodeContext() { + public AbstractStructure getChildrenNodes() { if (node == null) { node = new AbstractStructure<>(); } @@ -203,6 +202,10 @@ public boolean hasChildren() { return node != null && !node.isEmpty(); } + public void addChildNode(Test childTest) { + getChildrenNodes().add(childTest); + } + public void setStartTime(Date startTime) { this.startTime = startTime; } @@ -217,8 +220,8 @@ public void setEndTime(Date endTime) { private void setEndTimeFromChildren() { if (hasChildren()) { - setStartTime(getNodeContext().getFirst().getStartTime()); - setEndTime(getNodeContext().getLast().getEndTime()); + setStartTime(getChildrenNodes().getFirst().getStartTime()); + setEndTime(getChildrenNodes().getLast().getEndTime()); } else if (hasLog()) { Date lastLogEndTime = getLogContext().getLast().getTimestamp(); setEndTime(lastLogEndTime); @@ -275,7 +278,6 @@ private synchronized void updateStatus(Status logStatus) { } public void end() { - setStatus(Status.PASS); updateTestStatusRecursive(this); endChildrenRecursive(this); @@ -288,33 +290,19 @@ public void end() { } private synchronized void updateTestStatusRecursive(Test test) { - test.getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); - + + // Recursively update the status of all the children in the tree if (test.hasChildren()) { - test.getNodeContext().getAll().forEach(this::updateTestStatusRecursive); + test.getChildrenNodes().getAll().forEach(this::updateTestStatusRecursive); // First recursion here } - // if not all children are marked SKIP, then: - // ensure the parent has a status that is not SKIP - if (!test.isBehaviorDrivenType()) { - boolean hasNodeNotSkipped = test.getNodeContext().getAll() - .stream() - .anyMatch(x -> x.getStatus() != Status.SKIP); - - if (status == Status.SKIP && hasNodeNotSkipped) { - // reset status - status = Status.PASS; - // compute new status - test.getNodeContext().getAll() - .stream() - .filter(x -> x.getStatus() != Status.SKIP) - .forEach(this::updateTestStatusRecursive); - } - } + // At this point the subtree should be updated. Now we have to update the status + // of current node. + test.getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); } private void endChildrenRecursive(Test test) { - test.getNodeContext().getAll().forEach(Test::end); + test.getChildrenNodes().getAll().forEach(Test::end); } public AbstractStructure getLogContext() { @@ -368,7 +356,7 @@ public boolean hasCategory(String name) { } public boolean hasCategoryNode(String name) { - return getNodeContext().getAll() + return getChildrenNodes().getAll() .stream() .anyMatch(x -> x.hasCategory(name)); } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java index fd30efc..5ec6f70 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -496,8 +496,8 @@ private void onTestStartedHelper(Test test) { .append("level", test.getLevel()).append("name", test.getName()) .append("status", test.getStatus().toString()).append("description", test.getDescription()) .append("startTime", test.getStartTime()).append("endTime", test.getEndTime()) - .append("bdd", test.isBehaviorDrivenType()).append("leaf", test.getNodeContext().size() == 0) - .append("childNodesLength", test.getNodeContext().size()); + .append("bdd", test.isBehaviorDrivenType()).append("leaf", test.getChildrenNodes().size() == 0) + .append("childNodesLength", test.getChildrenNodes().size()); if (test.isBehaviorDrivenType()) { doc.append("bddType", test.getBehaviorDrivenType().getSimpleName()); @@ -520,7 +520,7 @@ private void updateTestDesc(Test test) { } private void updateTestChildrenCount(Test test) { - Document doc = new Document("childNodesLength", test.getNodeContext().size()); + Document doc = new Document("childNodesLength", test.getChildrenNodes().size()); testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); } @@ -596,8 +596,8 @@ public synchronized void onLogAdded(Test test, Log log) { private void endTestRecursive(Test test) { Document doc = new Document("status", test.getStatus().toString()).append("endTime", test.getEndTime()) - .append("duration", test.getRunDurationMillis()).append("leaf", test.getNodeContext().size() == 0) - .append("childNodesLength", test.getNodeContext().size()).append("categorized", test.hasCategory()) + .append("duration", test.getRunDurationMillis()).append("leaf", test.getChildrenNodes().size() == 0) + .append("childNodesLength", test.getChildrenNodes().size()).append("categorized", test.hasCategory()) .append("description", test.getDescription()); testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); diff --git a/src/test/java/com/aventstack/extentreports/api/TestInitializeNullValuesTest.java b/src/test/java/com/aventstack/extentreports/api/TestInitializeNullValuesTest.java index 590d7a0..773b0a3 100644 --- a/src/test/java/com/aventstack/extentreports/api/TestInitializeNullValuesTest.java +++ b/src/test/java/com/aventstack/extentreports/api/TestInitializeNullValuesTest.java @@ -87,7 +87,7 @@ public void nodeNameNull(Method method) { ExtentTest test = extent.createTest(method.getName()).fail("fail"); ExtentTest node = test.createNode(null); - Assert.assertEquals(test.getModel().getNodeContext().size(), 0); + Assert.assertEquals(test.getModel().getChildrenNodes().size(), 0); Assert.assertNull(node); } @@ -96,7 +96,7 @@ public void nodeNameEmpty(Method method) { ExtentTest test = extent.createTest(method.getName()).fail("fail"); ExtentTest node = test.createNode(""); - Assert.assertEquals(test.getModel().getNodeContext().size(), 0); + Assert.assertEquals(test.getModel().getChildrenNodes().size(), 0); Assert.assertNull(node); } diff --git a/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java b/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java index cd1a90d..86a1136 100644 --- a/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java +++ b/src/test/java/com/aventstack/extentreports/api/TestStartEndDateTimeTest.java @@ -116,7 +116,7 @@ public void testStartTimeWithManualSettingNodeLogSetter(Method method) throws In ExtentTest node = test.createNode(method.getName()); Thread.sleep(wait); node.pass("pass"); - test.getModel().setStartTime(test.getModel().getNodeContext().getLast().getEndTime()); + test.getModel().setStartTime(test.getModel().getChildrenNodes().getLast().getEndTime()); Assert.assertTrue(test.getModel().getStartTime().getTime() >= (init.getTime() + wait)); } @@ -145,7 +145,7 @@ public void testEndTimeWithManualSettingNodeLogSetter(Method method) throws Inte ExtentTest node = test.createNode(method.getName()); Thread.sleep(wait); node.pass("pass"); - test.getModel().setEndTime(test.getModel().getNodeContext().getLast().getEndTime()); + test.getModel().setEndTime(test.getModel().getChildrenNodes().getLast().getEndTime()); Assert.assertTrue(test.getModel().getEndTime().getTime() >= (init.getTime() + wait)); } diff --git a/src/test/java/com/aventstack/extentreports/model/TestModelTest.java b/src/test/java/com/aventstack/extentreports/model/TestModelTest.java index 66c6dee..bc15ad2 100644 --- a/src/test/java/com/aventstack/extentreports/model/TestModelTest.java +++ b/src/test/java/com/aventstack/extentreports/model/TestModelTest.java @@ -38,21 +38,21 @@ public void testNodeIsChildNode(Method method) { @Test public void testNodeContextIsEmpty(Method method) { ExtentTest t = extent.createTest(method.getName()); - Assert.assertTrue(t.getModel().getNodeContext().isEmpty()); + Assert.assertTrue(t.getModel().getChildrenNodes().isEmpty()); } @Test public void testNodeContextIsNotEmpty(Method method) { ExtentTest t = extent.createTest(method.getName()); t.createNode(method.getName()); - Assert.assertFalse(t.getModel().getNodeContext().isEmpty()); + Assert.assertFalse(t.getModel().getChildrenNodes().isEmpty()); } @Test public void testNodeContextFirstNotNull(Method method) { ExtentTest t = extent.createTest(method.getName()); t.createNode(method.getName()); - Assert.assertTrue(t.getModel().getNodeContext().getFirst()!=null); + Assert.assertTrue(t.getModel().getChildrenNodes().getFirst()!=null); } @Test @@ -60,7 +60,7 @@ public void testNodeContextFirstContent(Method method) { ExtentTest t = extent.createTest(method.getName()); String name = method.getName() + "x"; t.createNode(name); - Assert.assertTrue(t.getModel().getNodeContext().getFirst().getName().equals(name)); + Assert.assertTrue(t.getModel().getChildrenNodes().getFirst().getName().equals(name)); } @Test @@ -68,7 +68,7 @@ public void testNodeContextLastContent(Method method) { ExtentTest t = extent.createTest(method.getName()); String name = method.getName() + "x"; t.createNode(name); - Assert.assertTrue(t.getModel().getNodeContext().getLast().getName().equals(name)); + Assert.assertTrue(t.getModel().getChildrenNodes().getLast().getName().equals(name)); } @Test @@ -78,8 +78,8 @@ public void testNodeContextFirstLastContent(Method method) { t.createNode(name1); String name2 = method.getName() + "x2"; t.createNode(name2); - Assert.assertTrue(t.getModel().getNodeContext().getFirst().getName().equals(name1)); - Assert.assertTrue(t.getModel().getNodeContext().getLast().getName().equals(name2)); + Assert.assertTrue(t.getModel().getChildrenNodes().getFirst().getName().equals(name1)); + Assert.assertTrue(t.getModel().getChildrenNodes().getLast().getName().equals(name2)); } @Test @@ -89,8 +89,8 @@ public void testNodeContextIndexContent(Method method) { t.createNode(name1); String name2 = method.getName() + "x2"; t.createNode(name2); - Assert.assertTrue(t.getModel().getNodeContext().get(0).getName().equals(name1)); - Assert.assertTrue(t.getModel().getNodeContext().get(1).getName().equals(name2)); + Assert.assertTrue(t.getModel().getChildrenNodes().get(0).getName().equals(name1)); + Assert.assertTrue(t.getModel().getChildrenNodes().get(1).getName().equals(name2)); } @Test From 74bcc0b574c92ca1c074a743691e65470518ee78 Mon Sep 17 00:00:00 2001 From: Virender Date: Sun, 12 May 2019 11:43:01 +0530 Subject: [PATCH 27/77] Fixing the recursion --- src/main/java/com/aventstack/extentreports/model/Test.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index 7271f0f..da90311 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -290,6 +290,9 @@ public void end() { } private synchronized void updateTestStatusRecursive(Test test) { + // Update this test first, based on the logs + test.getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); + // Recursively update the status of all the children in the tree if (test.hasChildren()) { @@ -298,7 +301,7 @@ private synchronized void updateTestStatusRecursive(Test test) { // At this point the subtree should be updated. Now we have to update the status // of current node. - test.getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); + test.getChildrenNodes().getAll().forEach(x -> updateStatus(x.getStatus())); } private void endChildrenRecursive(Test test) { From fa758b18ec90a338b408287bb7400dcbc6f827eb Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 26 Dec 2019 11:50:03 -0800 Subject: [PATCH 28/77] Create package.json --- package.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..6ce768c --- /dev/null +++ b/package.json @@ -0,0 +1,4 @@ +{ + "name": "extentreports", + "version": "4.0.9" +} \ No newline at end of file From d17d1b01392ba45360de620c67f8bf933bf03833 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 26 Dec 2019 12:07:14 -0800 Subject: [PATCH 29/77] Update license --- pom-nexus.xml | 4 ++-- pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom-nexus.xml b/pom-nexus.xml index 04f82ab..9932fa8 100644 --- a/pom-nexus.xml +++ b/pom-nexus.xml @@ -18,8 +18,8 @@ - The BSD 3-Clause License - http://opensource.org/licenses/BSD-3-Clause + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt diff --git a/pom.xml b/pom.xml index e6b9b6e..34f60ff 100644 --- a/pom.xml +++ b/pom.xml @@ -18,8 +18,8 @@ - The BSD 3-Clause License - http://opensource.org/licenses/BSD-3-Clause + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt From 779ab1129a82b73831cadc2dab1f528aef05843e Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 26 Dec 2019 13:45:11 -0800 Subject: [PATCH 30/77] Delete package.json --- package.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 package.json diff --git a/package.json b/package.json deleted file mode 100644 index 6ce768c..0000000 --- a/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "extentreports", - "version": "4.0.9" -} \ No newline at end of file From 586fc528fbdc27f73237821091602e71372651c9 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 26 Dec 2019 13:45:26 -0800 Subject: [PATCH 31/77] removes unused imports --- .../com/aventstack/extentreports/reporter/AbstractReporter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java index 2a61c82..cb0fbfc 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java @@ -2,11 +2,9 @@ import java.util.Calendar; import java.util.Date; -import java.util.List; import com.aventstack.extentreports.AnalysisStrategy; import com.aventstack.extentreports.ReportAggregates; -import com.aventstack.extentreports.Status; /** * A base class for all Reporter types From 8e11d35580aa0bcc81ff8114118746c18b8f0695 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 26 Dec 2019 13:45:35 -0800 Subject: [PATCH 32/77] bump cdn commit --- .../com/aventstack/extentreports/view/spark/partials/head.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl index c11f164..cbe0468 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl @@ -1,4 +1,4 @@ -<#assign resourceCDN=config.getValue('resourceCDN') cdnURI="cdn.rawgit.com/extent-framework/extent-github-cdn/" csscommit="9be0dad" jscommit="24cb10e" iconcommit="d74480e"> +<#assign resourceCDN=config.getValue('resourceCDN') cdnURI="cdn.rawgit.com/extent-framework/extent-github-cdn/" csscommit="4dd3b1c" jscommit="24cb10e" iconcommit="d74480e"> <#if resourceCDN=="extentreports"> <#assign cdnURI="extentreports.com/resx" csscommit="" jscommit="" iconcommit=""> From 02068e55755a04e0d99deb2d97492b2bc4ec36cb Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 26 Dec 2019 13:48:20 -0800 Subject: [PATCH 33/77] bump version to 4.0.10-SNAPSHOT --- pom-nexus.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom-nexus.xml b/pom-nexus.xml index 9932fa8..629dcf5 100644 --- a/pom-nexus.xml +++ b/pom-nexus.xml @@ -4,7 +4,7 @@ com.aventstack extentreports - 4.0.9 + 4.0.10-SNAPSHOT extentreports www.extentreports.com @@ -159,7 +159,7 @@ - 7A7DAF8A + 41414BBD anshooarora From 21712cc9fc71af2a91eb96d641f4cf2e6ea23ed4 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Wed, 1 Jan 2020 15:57:51 -0800 Subject: [PATCH 34/77] initial --- pom.xml | 33 +- .../extentreports/AnalysisStrategy.java | 15 +- .../ExceptionTestContextImpl.java | 48 - .../extentreports/ExtentObservable.java | 600 ----- .../extentreports/ExtentReporter.java | 33 - .../extentreports/ExtentReports.java | 730 +++--- .../aventstack/extentreports/ExtentTest.java | 2335 ++++++++--------- .../extentreports/GherkinKeyword.java | 105 +- .../GherkinKeywordNotFoundException.java | 9 +- .../aventstack/extentreports/IAddsMedia.java | 55 + ...vice.java => IAnalysisStrategyMethod.java} | 4 +- .../InvalidAnalysisStrategyException.java | 6 +- .../com/aventstack/extentreports/Main.java | 45 + .../extentreports/MediaEntityBuilder.java | 101 +- .../MediaEntityModelProvider.java | 6 +- .../extentreports/ReportAggregates.java | 31 +- .../ReportAggregatesBuilder.java | 67 +- .../ReportAggregatesListener.java | 163 +- .../extentreports/ReportConfigurator.java | 30 +- .../extentreports/ReportObservable.java | 574 ++++ .../extentreports/ReportService.java | 12 +- .../extentreports/ReportStatusStats.java | 834 +++--- .../aventstack/extentreports/RunResult.java | 3 +- .../extentreports/SourceProvider.java | 12 - .../com/aventstack/extentreports/Status.java | 1 - .../extentreports/StatusConfigurator.java | 47 +- .../extentreports/SystemAttributeContext.java | 29 - .../TestAttributeTestContextProvider.java | 66 - .../extentreports/TestListener.java | 164 +- .../aventstack/extentreports/TestRemover.java | 67 - .../ConfigurationBuilder.java} | 40 +- .../configuration/ConfigurationStore.java | 43 + .../convert/JsonDeserializer.java | 24 + .../convert/TestModelReportBuilder.java | 38 + .../ExtentTestInterruptedException.java | 17 - .../exceptions/InvalidFileException.java | 21 - .../externalconfig/model/ConfigMap.java | 45 - .../extentreports/gherkin/GherkinDialect.java | 32 +- .../gherkin/GherkinDialectProvider.java | 106 +- .../extentreports/gherkin/model/And.java | 9 +- .../extentreports/gherkin/model/Asterisk.java | 9 +- .../gherkin/model/Background.java | 9 +- .../extentreports/gherkin/model/But.java | 9 +- .../extentreports/gherkin/model/Feature.java | 9 +- .../gherkin/model/GherkinModelSerializer.java | 23 + .../extentreports/gherkin/model/Given.java | 9 +- .../gherkin/model/IGherkinFormatterModel.java | 4 +- .../extentreports/gherkin/model/Scenario.java | 9 +- .../gherkin/model/ScenarioOutline.java | 9 +- .../extentreports/gherkin/model/Then.java | 9 +- .../extentreports/gherkin/model/When.java | 9 +- .../extentreports/io/FileWriterBuffered.java | 35 + .../extentreports/io/ResourceUtil.java | 54 + .../extentreports/markuputils/CodeBlock.java | 96 +- .../extentreports/markuputils/Markup.java | 2 +- .../markuputils/MarkupHelper.java | 52 +- .../markuputils/MarkupTemplate.java | 10 + .../mediastorage/KlovMediaStorageHandler.java | 8 +- .../impl/HttpMediaManagerImplKlov.java | 19 +- .../model/AbstractStructure.java | 11 +- .../extentreports/model/Attribute.java | 69 +- .../extentreports/model/Author.java | 19 +- .../extentreports/model/Category.java | 19 +- .../extentreports/model/Device.java | 15 +- .../extentreports/model/ExceptionInfo.java | 50 +- .../model/ExceptionTestContext.java | 31 - .../extentreports/model/IAddsMedia.java | 59 - .../aventstack/extentreports/model/Log.java | 221 +- .../aventstack/extentreports/model/Media.java | 145 +- .../extentreports/model/MediaType.java | 6 - .../extentreports/model/ScreenCapture.java | 37 +- .../extentreports/model/Screencast.java | 19 - .../extentreports/model/SystemAttribute.java | 25 +- .../aventstack/extentreports/model/Test.java | 846 +++--- .../extentreports/model/TestAttribute.java | 31 - .../model/TestAttributeTestContext.java | 84 - .../model/context/ExceptionTestContext.java | 33 + .../context/ExceptionTestContextStore.java | 41 + .../model/context/SystemAttributeContext.java | 35 + .../context/TestAttributeTestContext.java | 84 + .../TestAttributeTestContextStore.java | 62 + .../model/context/helpers/TestRemover.java | 65 + .../model/service/LogService.java | 11 + .../model/service/TestService.java | 75 + .../OfflineResxDelegate.java | 16 +- .../reporter/AbstractReporter.java | 211 +- .../reporter/BasicFileReporter.java | 266 +- .../reporter/ConfigurableReporter.java | 59 +- .../reporter/{impl => }/ConsoleLogger.java | 7 +- .../reporter/ExtentAventReporter.java | 33 - .../reporter/ExtentBDDReporter.java | 33 - .../reporter/ExtentCardsReporter.java | 33 - .../reporter/ExtentEmailReporter.java | 40 - .../reporter/ExtentHtmlReporter.java | 79 +- .../reporter/ExtentKlovReporter.java | 682 ----- .../reporter/ExtentLoggerReporter.java | 20 +- .../reporter/ExtentReporter.java | 38 + .../reporter/ExtentSparkReporter.java | 135 +- .../reporter/ExtentTabularReporter.java | 33 - .../extentreports/reporter/JsonFormatter.java | 47 + .../reporter/ReportAppendable.java | 4 +- .../extentreports/reporter/TestListener.java | 96 + .../extentreports/reporter/ViewStyle.java | 5 + .../configuration/BasicConfiguration.java | 84 +- .../configuration/BasicFileConfiguration.java | 138 +- .../ExtentHtmlReporterConfiguration.java | 138 +- .../ExtentLoggerFormatterConfiguration.java | 107 - .../ExtentLoggerReporterConfiguration.java | 90 + .../ExtentSparkReporterConfiguration.java | 135 +- .../configuration/IReporterConfiguration.java | 4 +- .../reporter/configuration/Protocol.java | 7 +- .../reporter/configuration/ResourceCDN.java | 16 - .../RichViewReporterConfiguration.java | 115 +- .../reporter/configuration/Theme.java | 7 +- .../templating/FreemarkerTemplate.java | 59 + .../templating/TemplateConfig.java | 18 + .../extentreports/utils/DateUtil.java | 26 - .../extentreports/utils/ExceptionUtil.java | 49 +- .../extentreports/utils/FileUtil.java | 137 +- .../extentreports/utils/IntUtils.java | 17 - .../extentreports/utils/MongoUtil.java | 17 +- .../extentreports/utils/Reader.java | 38 - .../extentreports/utils/ResourceUtil.java | 56 - .../extentreports/utils/StringUtil.java | 21 +- .../extentreports/utils/Writer.java | 34 - .../extentreports/markup/codeblock.ftl | 3 + .../extentreports/markup/codeblock.json.ftl | 9 + .../view/commons/commons-dashboard.ftl | 2 +- .../view/commons/commons-inject-css.ftl | 2 +- .../view/commons/commons-inject-js.ftl | 2 +- .../view/commons/commons-macros.ftl | 2 +- .../view/commons/commons-variables.ftl | 16 +- .../view/logger/logger-dashboard.ftl | 4 +- .../view/logger/logger-exception.ftl | 4 +- .../extentreports/view/logger/logger-tag.ftl | 4 +- .../extentreports/view/logger/logger-test.ftl | 6 +- .../extentreports/view/spark/dashboard.ftl | 16 +- .../view/spark/macros/attributes.ftl | 6 +- .../extentreports/view/spark/macros/log.ftl | 2 +- .../view/spark/macros/recurse_nodes.ftl | 12 +- .../view/spark/partials/bdd-content.ftl | 8 +- .../view/spark/partials/head.ftl | 12 +- .../view/spark/partials/navbar.ftl | 2 +- .../view/spark/partials/scripts.ftl | 4 +- .../view/spark/partials/standard-content.ftl | 8 +- .../extentreports/view/spark/tag.ftl | 4 +- .../extentreports/view/spark/test.ftl | 10 +- .../author-view/v3-html-author-view.ftl | 2 +- .../category-view/v3-html-category-view.ftl | 4 +- .../exception-view/v3-html-exception-view.ftl | 2 +- .../view/v3html/test-view/v3-html-bdd.ftl | 28 +- .../v3html/test-view/v3-html-standard.ftl | 38 +- .../v3html/test-view/v3-html-test-view.ftl | 6 +- .../view/v3html/v3-html-head.ftl | 22 +- .../view/v3html/v3-html-index.ftl | 48 +- .../extentreports/view/v3html/v3-html-nav.ftl | 10 +- .../com/aventstack/extentreports/Base.java | 3 +- .../extentreports/api/BddAttributesTest.java | 41 +- .../api/BddWithStepStatusHierarchyTest.java | 21 +- .../extentreports/api/GherkinKeywordTest.java | 30 +- .../api/MediaEntityBuilderTest.java | 7 +- .../extentreports/api/NodeAttributesTest.java | 10 +- .../extentreports/api/NodeMediaTest.java | 10 +- .../api/NodeSingleLogsStatusTest.java | 6 +- .../api/NodesStatusHierarchyTest.java | 322 +-- .../api/RemoveStartedTestsFromExtentTest.java | 52 +- .../extentreports/api/TestAttributesTest.java | 10 +- .../extentreports/api/TestIdsTest.java | 2 +- .../api/TestInitializeNullValuesTest.java | 4 +- .../extentreports/api/TestMediaTest.java | 10 +- .../api/TestStartEndDateTimeTest.java | 7 +- .../extentreports/common/ExtentManager.java | 2 +- .../common/ExtentTestNGIReporterListener.java | 2 +- .../common/ExtentTestNGListener.java | 2 +- .../mediastorage/LocalMediaStorageTest.java | 4 +- .../extentreports/model/TestIdsTest.java | 2 +- .../extentreports/model/TestMediaTest.java | 10 +- .../extentreports/model/TestModelTest.java | 77 +- ...tmlBasicFileReporterConfigurationTest.java | 196 +- .../HtmlConfigurableReporterTest.java | 106 +- ...HtmlRichViewReporterConfigurationTest.java | 29 +- ...erBasicFileReporterConfigurationTest2.java | 196 +- .../LoggerConfigurableReporterTest.java | 14 +- ...ggerRichViewReporterConfigurationTest.java | 20 +- .../components/ExtentTestNGReportBuilder.java | 2 +- 185 files changed, 6439 insertions(+), 7283 deletions(-) delete mode 100644 src/main/java/com/aventstack/extentreports/ExceptionTestContextImpl.java delete mode 100644 src/main/java/com/aventstack/extentreports/ExtentObservable.java delete mode 100644 src/main/java/com/aventstack/extentreports/ExtentReporter.java rename src/main/java/com/aventstack/extentreports/{exceptions => }/GherkinKeywordNotFoundException.java (53%) create mode 100644 src/main/java/com/aventstack/extentreports/IAddsMedia.java rename src/main/java/com/aventstack/extentreports/{AnalysisStrategyService.java => IAnalysisStrategyMethod.java} (83%) rename src/main/java/com/aventstack/extentreports/{exceptions => }/InvalidAnalysisStrategyException.java (81%) create mode 100644 src/main/java/com/aventstack/extentreports/Main.java create mode 100644 src/main/java/com/aventstack/extentreports/ReportObservable.java delete mode 100644 src/main/java/com/aventstack/extentreports/SourceProvider.java delete mode 100644 src/main/java/com/aventstack/extentreports/SystemAttributeContext.java delete mode 100644 src/main/java/com/aventstack/extentreports/TestAttributeTestContextProvider.java delete mode 100644 src/main/java/com/aventstack/extentreports/TestRemover.java rename src/main/java/com/aventstack/extentreports/{externalconfig/ConfigLoader.java => configuration/ConfigurationBuilder.java} (65%) create mode 100644 src/main/java/com/aventstack/extentreports/configuration/ConfigurationStore.java create mode 100644 src/main/java/com/aventstack/extentreports/convert/JsonDeserializer.java create mode 100644 src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java delete mode 100644 src/main/java/com/aventstack/extentreports/exceptions/ExtentTestInterruptedException.java delete mode 100644 src/main/java/com/aventstack/extentreports/exceptions/InvalidFileException.java delete mode 100644 src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java create mode 100644 src/main/java/com/aventstack/extentreports/gherkin/model/GherkinModelSerializer.java create mode 100644 src/main/java/com/aventstack/extentreports/io/FileWriterBuffered.java create mode 100644 src/main/java/com/aventstack/extentreports/io/ResourceUtil.java create mode 100644 src/main/java/com/aventstack/extentreports/markuputils/MarkupTemplate.java delete mode 100644 src/main/java/com/aventstack/extentreports/model/ExceptionTestContext.java delete mode 100644 src/main/java/com/aventstack/extentreports/model/IAddsMedia.java delete mode 100644 src/main/java/com/aventstack/extentreports/model/MediaType.java delete mode 100644 src/main/java/com/aventstack/extentreports/model/Screencast.java delete mode 100644 src/main/java/com/aventstack/extentreports/model/TestAttribute.java delete mode 100644 src/main/java/com/aventstack/extentreports/model/TestAttributeTestContext.java create mode 100644 src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContext.java create mode 100644 src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContextStore.java create mode 100644 src/main/java/com/aventstack/extentreports/model/context/SystemAttributeContext.java create mode 100644 src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContext.java create mode 100644 src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContextStore.java create mode 100644 src/main/java/com/aventstack/extentreports/model/context/helpers/TestRemover.java create mode 100644 src/main/java/com/aventstack/extentreports/model/service/LogService.java create mode 100644 src/main/java/com/aventstack/extentreports/model/service/TestService.java rename src/main/java/com/aventstack/extentreports/{resource => offline}/OfflineResxDelegate.java (71%) rename src/main/java/com/aventstack/extentreports/reporter/{impl => }/ConsoleLogger.java (90%) delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentReporter.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/TestListener.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ViewStyle.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerFormatterConfiguration.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerReporterConfiguration.java delete mode 100644 src/main/java/com/aventstack/extentreports/reporter/configuration/ResourceCDN.java create mode 100644 src/main/java/com/aventstack/extentreports/templating/FreemarkerTemplate.java create mode 100644 src/main/java/com/aventstack/extentreports/templating/TemplateConfig.java delete mode 100644 src/main/java/com/aventstack/extentreports/utils/DateUtil.java delete mode 100644 src/main/java/com/aventstack/extentreports/utils/IntUtils.java delete mode 100644 src/main/java/com/aventstack/extentreports/utils/Reader.java delete mode 100644 src/main/java/com/aventstack/extentreports/utils/ResourceUtil.java delete mode 100644 src/main/java/com/aventstack/extentreports/utils/Writer.java create mode 100644 src/main/resources/com/aventstack/extentreports/markup/codeblock.ftl create mode 100644 src/main/resources/com/aventstack/extentreports/markup/codeblock.json.ftl diff --git a/pom.xml b/pom.xml index 34f60ff..75b6125 100644 --- a/pom.xml +++ b/pom.xml @@ -1,10 +1,11 @@ - 4.0.0 com.aventstack extentreports - 4.0.10-SNAPSHOT + 4.1.0-SNAPSHOT extentreports www.extentreports.com @@ -19,7 +20,7 @@ The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt + http://www.apache.org/licenses/LICENSE-2.0.txt @@ -36,7 +37,7 @@ UTF-8 - 3.3.0 + 3.12.0 4.5.2 @@ -44,17 +45,7 @@ org.freemarker freemarker - 2.3.23 - - - org.mongodb - mongodb-driver - ${mongodb.version} - - - org.mongodb - bson - ${mongodb.version} + 2.3.29 org.apache.httpcomponents @@ -69,7 +60,17 @@ com.google.code.gson gson - 2.8.5 + 2.8.6 + + + org.mongodb + mongodb-driver + ${mongodb.version} + + + org.mongodb + bson + ${mongodb.version} org.testng diff --git a/src/main/java/com/aventstack/extentreports/AnalysisStrategy.java b/src/main/java/com/aventstack/extentreports/AnalysisStrategy.java index aff7853..fdfca02 100644 --- a/src/main/java/com/aventstack/extentreports/AnalysisStrategy.java +++ b/src/main/java/com/aventstack/extentreports/AnalysisStrategy.java @@ -5,15 +5,12 @@ *

    * Available strategies are: *

      - *
    • BDD: Strategy for BDD-style (Gherkin) tests
    • - *
    • CLASS: Used for 2 levels: Class, Test
    • - *
    • SUITE: Used for 3 levels: Suite, Class, Test
    • - *
    • TEST: Used for 1 level only: Test
    • + *
    • BDD: Strategy for BDD-style (Gherkin) tests
    • + *
    • CLASS: Used for 2 levels: Class, Test
    • + *
    • SUITE: Used for 3 levels: Suite, Class, Test
    • + *
    • TEST: Used for 1 level only: Test
    • *
    */ public enum AnalysisStrategy { - BDD, - CLASS, - SUITE, - TEST -} + BDD, CLASS, SUITE, TEST +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ExceptionTestContextImpl.java b/src/main/java/com/aventstack/extentreports/ExceptionTestContextImpl.java deleted file mode 100644 index 502ca35..0000000 --- a/src/main/java/com/aventstack/extentreports/ExceptionTestContextImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.aventstack.extentreports; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import com.aventstack.extentreports.model.ExceptionInfo; -import com.aventstack.extentreports.model.ExceptionTestContext; -import com.aventstack.extentreports.model.Test; - -/** - * Provides and tracks the collection of tests segregated by the type of {@link Exception} - * - */ -public class ExceptionTestContextImpl { - private List exTestContextList; - - public ExceptionTestContextImpl() { - exTestContextList = new ArrayList<>(); - } - - public void setExceptionContext(ExceptionInfo ei, Test test) { - Optional exOptionalTestContext = exTestContextList - .stream() - .filter(x -> x.getExceptionInfo().getExceptionName().equals(ei.getExceptionName())) - .findFirst(); - - if (exOptionalTestContext.isPresent()) { - List testList = exOptionalTestContext.get().getTestList(); - - boolean b = testList.stream() - .anyMatch(t -> t.getID() == test.getID()); - - if (!b) { - exOptionalTestContext.get().setTest(test); - } - } - else { - ExceptionTestContext exTestContext = new ExceptionTestContext(ei); - exTestContext.setTest(test); - exTestContextList.add(exTestContext); - } - } - - public List getExceptionTestContextList() { - return exTestContextList; - } -} diff --git a/src/main/java/com/aventstack/extentreports/ExtentObservable.java b/src/main/java/com/aventstack/extentreports/ExtentObservable.java deleted file mode 100644 index 9e5d339..0000000 --- a/src/main/java/com/aventstack/extentreports/ExtentObservable.java +++ /dev/null @@ -1,600 +0,0 @@ -package com.aventstack.extentreports; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.aventstack.extentreports.model.Author; -import com.aventstack.extentreports.model.Category; -import com.aventstack.extentreports.model.Device; -import com.aventstack.extentreports.model.Log; -import com.aventstack.extentreports.model.ScreenCapture; -import com.aventstack.extentreports.model.Screencast; -import com.aventstack.extentreports.model.SystemAttribute; -import com.aventstack.extentreports.model.Test; -import com.aventstack.extentreports.reporter.BasicFileReporter; - -abstract class ExtentObservable - implements ReportService { - - /** - * The current AnalysisStrategy for the run session. This decides the technique used - * to count the test status at differing levels. For example, for a BDD style report, - * the levels to be calculated are Feature, Scenario and Step (3 levels). For a generic, - * non-BDD style report, levels can be dynamic. For a non-BDD style report, levels typically - * consist of: - * - *

    - * 1 level: Test
    - * Test
    - * - Event - * - *

    - * 2 levels: Test & node
    - * Test
    - Node
    -- Event - * - *

    - * 2 levels: Test, the leaf-node
    - * Test
    - Node
    -- Leaf Node
    --- Event - * - */ - private AnalysisStrategy strategy = AnalysisStrategy.TEST; - - /** - * Use this setting when building post-execution reports, such as from TestNG IReporter. - * This setting allows setting test with your own variables and prevent update by Extent. - * As of today, with this enabled, Extent does not use time-stamps for tests at the time - * they were created - */ - private boolean usesManualConfiguration = false; - - /** - * The status of the entire report or build - */ - private Status reportStatus = Status.PASS; - - /** - * Time the report or build was started - */ - private Date reportStartDate = Calendar.getInstance().getTime(); - - /** - * Time the report or build ended. This value is updated everytime flush - * is called - */ - private Date reportEndDate; - - /** - * A collection of tests arranged by category - */ - private TestAttributeTestContextProvider categoryContext = new TestAttributeTestContextProvider<>(); - - /** - * A collection of tests arranged by author - */ - private TestAttributeTestContextProvider authorContext = new TestAttributeTestContextProvider<>(); - - /** - * A collection of tests arranged by author - */ - private TestAttributeTestContextProvider deviceContext = new TestAttributeTestContextProvider<>(); - - - /** - * A collection of tests arranged by exception - */ - private ExceptionTestContextImpl exceptionContextBuilder = new ExceptionTestContextImpl(); - - /** - * A context of all system or environment variables - */ - private SystemAttributeContext systemAttributeContext = new SystemAttributeContext(); - - /** - * A list of all {@link ExtentReporter} reporters started by the attachReporter - * method - */ - private List reporterList = new ArrayList<>(); - - /** - * Any logs added by to the test runner can be added to Extent - * - *

    - * TestNG Example: - * - *

    - * Setting logs with TestNG: - * - *

    Reporter.log("hello world")
    - * - *

    - * Informing Extent of any logs added: - *

    -	 * for (String s : Reporter.getOutput()) {
    -     *       extent.setTestRunnerOutput(s);
    -     * }
    -     * 
    - */ - private List testRunnerLogs = new ArrayList<>(); - - /** - * A list of all tests created - */ - private List testList = new ArrayList<>(); - - /** - * Instance of {@link ReportStatusStats} - */ - private ReportStatusStats stats = new ReportStatusStats(strategy); - - /** - * A unique collection of statuses tests are marked with - * - *

    - * Consider a report having 10 tests: - * - *

      - *
    1. Test1: PASS
    2. - *
    3. Test2: PASS
    4. - *
    5. Test3: PASS
    6. - *
    7. Test4: SKIP
    8. - *
    9. Test5: SKIP
    10. - *
    11. Test6: FAIL
    12. - *
    13. Test7: PASS
    14. - *
    15. Test8: PASS
    16. - *
    17. Test9: FAIL
    18. - *
    19. Test10: PASS
    20. - *
    - * - *

    - * Distinct list of contained status: - * - *

      - *
    1. PASS
    2. - *
    3. SKIP
    4. - *
    5. FAIL
    6. - *
    - */ - private Set statusSet = new HashSet(); - - protected ExtentObservable() { } - - /** - * Subscribe the reporter to receive updates when making calls to the API - * - * @param reporter {@link ExtentReporter} reporter - */ - protected void register(ExtentReporter reporter) { - reporterList.add(reporter); - reporter.start(); - } - - /** - * Unsubscribe the reporter. Calling unsubscribe will call the stop method - * and also remove the reporter from the list of started reporters - * - * @param reporter {@link ExtentReporter} reporter to unsubscribe - */ - protected void deregister(ExtentReporter reporter) { - - if(reporterList.contains((Object) reporter)){ - reporter.stop(); - reporterList.remove(reporter); - } - } - - /** - * Retrieve a list of all started reporters - * - * @return a list of {@link ExtentReporter} objects - */ - protected List getReporterCollection() { - return reporterList; - } - - /** - * Saves the started test and notifies all started reporters - * - * @param test a {@link Test} object - */ - protected synchronized void saveTest(Test test) { - testList.add(test); - reporterList.forEach(x -> x.onTestStarted(test)); - } - - /** - * Removes the test and notifies all started reporters - * - * @param test a {@link Test} object - */ - protected synchronized void removeTest(Test test) { - removeTestTestList(test); - removeTestTestAttributeContext(test); - reporterList.forEach(x -> x.onTestRemoved(test)); - } - - /** - * Removes a test from test list - * - * @param test a {@link Test} object - */ - private void removeTestTestList(Test test) { - TestRemover.remove(testList, test); - refreshReportEntities(); - } - - /** - * Removes test from test list of each context - * - * @param test a {@link Test} object - */ - private void removeTestTestAttributeContext(Test test) { - if (test.hasCategory()) { - categoryContext.removeTest(test); - } - if (test.hasAuthor()) { - authorContext.removeTest(test); - } - if (test.hasDevice()) { - deviceContext.removeTest(test); - } - } - - /** - * Refreshes report entities such as {@link ReportStatusStats} and list of distinct {@link Status} - */ - private void refreshReportEntities() { - refreshReportStats(); - refreshStatusList(); - } - - /** - * Refresh and notify all reports of {@link ReportStatusStats} - */ - private void refreshReportStats() { - stats.refresh(testList); - } - - /** - * Refresh and notify all reports of distinct status assigned to tests - */ - private synchronized void refreshStatusList() { - statusSet.clear(); - refreshStatusList(testList); - } - - /** - * Refreshes distinct status list - * - * @param list a list of started {@link Test} - */ - private synchronized void refreshStatusList(List list) { - if (list == null || list.isEmpty()) - return; - - list.forEach(x -> statusSet.add(x.getStatus())); - list.forEach(x -> refreshStatusList(x.getChildrenNodes().getAll())); - } - - /** - * Notify reporters of the added node - * - * @param node a {@link Test} node - */ - synchronized void addNode(Test node) { - reporterList.forEach(x -> x.onNodeStarted(node)); - } - - /** - * Notifies reporters with information of added {@link Log} - * - * @param test {@link Test} to which the event is added - * @param log {@link Log} - */ - synchronized void addLog(Test test, Log log) { - reporterList.forEach(x -> x.onLogAdded(test, log)); - } - - /** - * Notifies reporters with information of added {@link Category} - * - * @param test {@link Test} to which the Category is added - * @param category {@link Category} - */ - synchronized void assignCategory(Test test, Category category) { - reporterList.forEach(x -> x.onCategoryAssigned(test, category)); - } - - /** - * Notifies reporters with information of added {@link Author} - * - * @param test {@link Test} to which the Author is added - * @param author {@link Author} - */ - synchronized void assignAuthor(Test test, Author author) { - reporterList.forEach(x -> x.onAuthorAssigned(test, author)); - } - - /** - * Notifies reporters with information of added {@link Author} - * - * @param test {@link Test} to which the Device is added - * @param device {@link Device} - */ - synchronized void assignDevice(Test test, Device device) { - reporterList.forEach(x -> x.onDeviceAssigned(test, device)); - } - - /** - * Notifies reporters with information of added {@link ScreenCapture} - * - * @param test {@link Test} to which the ScreenCapture is added - * @param screenCapture {@link ScreenCapture} - * - * @throws IOException thrown if the {@link ScreenCapture} is not found - */ - synchronized void addScreenCapture(Test test, ScreenCapture screenCapture) throws IOException { - for (ExtentReporter r : reporterList) { - r.onScreenCaptureAdded(test, screenCapture); - } - } - - /** - * Notifies reporters with information of added {@link ScreenCapture} - * - * @param test {@link Log} to which the ScreenCapture is added - * @param screenCapture {@link ScreenCapture} - * - * @throws IOException thrown if the {@link ScreenCapture} is not found - */ - synchronized void addScreenCapture(Log log, ScreenCapture screenCapture) throws IOException { - for (ExtentReporter r : reporterList) { - r.onScreenCaptureAdded(log, screenCapture); - } - } - - /** - * Notifies reporters with information of added {@link Screencast} - * - * @param test {@link Test} to which the ScreenCast is added - * @param sc {@link Screencast} - * - * @throws IOException thrown if the {@link Screencast} is not found - */ - synchronized void addScreencast(Test test, Screencast screencast) throws IOException { - for (ExtentReporter r : reporterList) { - r.onScreencastAdded(test, screencast); - } - } - - /** - * Returns the context of author with the list of tests for each - * - * @return a {@link TestAttributeTestContextProvider} object - */ - protected TestAttributeTestContextProvider getAuthorContextInfo() { - return authorContext; - } - - /** - * Updates the status of the report or build - * - * @param status a {@link Status} - */ - private void updateReportStatus(Status status) { - int statusIndex = Status.getStatusHierarchy().indexOf(status); - int reportStatusIndex = Status.getStatusHierarchy().indexOf(reportStatus); - - reportStatus = statusIndex < reportStatusIndex - ? status - : reportStatus; - } - - /** - * Ends the test - * - * @param test a {@link Test} object - */ - private void endTest(Test test) { - test.end(); - updateReportStatus(test.getStatus()); - } - - /** - * Collects and updates all run information and notifies all reporters. Depending upon the - * type of reporter, additional events can occur such as: - * - *
      - *
    • A file written to disk (eg. case of {@link BasicFileReporter}
    • - *
    • A database being updated (eg. case of KlovReporter)
    • - *
    - */ - protected synchronized void flush() { - generateRecentStatus(); - notifyReporters(); - } - - /** - * Collects run information from all tests for assigned {@link Category}, {@link Author}, - * Exception, Nodes. This also ends and updates all internal test information and - * refreshes {@link ReportStatusStats} and the distinct list of {@link Status} - */ - public synchronized void generateRecentStatus() { - if (testList == null || testList.isEmpty()) - return; - - reportEndDate = Calendar.getInstance().getTime(); - - refreshReportEntities(); - - for (Test test : testList) { - endTest(test); - test.setUseManualConfiguration(getAllowManualConfig()); - if (test.hasCategory()) { - test.getCategoryContext().getAll() - .forEach(x -> categoryContext.setAttributeContext((Category)x, test)); - } - if (test.hasAuthor()) { - test.getAuthorContext().getAll() - .forEach(x -> authorContext.setAttributeContext((Author)x, test)); - } - if (test.hasDevice()) { - test.getDeviceContext().getAll() - .forEach(x -> deviceContext.setAttributeContext((Device)x, test)); - } - if (test.hasException()) { - test.getExceptionInfoList() - .forEach(x -> exceptionContextBuilder.setExceptionContext(x, test)); - } - if (test.hasChildren()) { - for (Test node : test.getChildrenNodes().getAll()) { - copyNodeAttributeAndRunTimeInfoToAttributeContexts(node); - node.setUseManualConfiguration(getAllowManualConfig()); - } - } - } - - updateReportStartTimeForManualConfigurationSetting(); - } - - /** - * In case where manual configuration is used, calculate the correct timestamps based upon - * the timestamps assigned to tests - */ - private void updateReportStartTimeForManualConfigurationSetting() { - if (getAllowManualConfig() && !testList.isEmpty()) { - Date minDate = testList.stream() - .map(t -> t.getStartTime()) - .min(Date::compareTo) - .get(); - Date maxDate = testList.stream() - .map(t -> t.getEndTime()) - .max(Date::compareTo) - .get(); - reportStartDate = reportStartDate.getTime() > minDate.getTime() ? minDate : reportStartDate; - reportEndDate = reportEndDate.getTime() < maxDate.getTime() ? maxDate : reportEndDate; - } - } - - /** - * Traverse all nodes and refresh {@link Category}, {@link Author}, Exception and Node context - * information - * - * @param node a {@link Test} node - */ - private void copyNodeAttributeAndRunTimeInfoToAttributeContexts(Test node) { - if (node.hasCategory()) { - node.getCategoryContext().getAll() - .forEach(x -> categoryContext.setAttributeContext((Category)x, node)); - } - if (node.hasAuthor()) { - node.getAuthorContext().getAll() - .forEach(x -> authorContext.setAttributeContext((Author)x, node)); - } - if (node.hasDevice()) { - node.getDeviceContext().getAll() - .forEach(x -> deviceContext.setAttributeContext((Device)x, node)); - } - if (node.hasException()) { - node.getExceptionInfoList() - .forEach(x -> exceptionContextBuilder.setExceptionContext(x, node)); - } - if (node.hasChildren()) { - node.getChildrenNodes().getAll() - .forEach(this::copyNodeAttributeAndRunTimeInfoToAttributeContexts); - } - } - - /** - * Notify all reporters with complete run information - */ - private synchronized void notifyReporters() { - if (!testList.isEmpty() && testList.get(0).isBehaviorDrivenType()) { - strategy = AnalysisStrategy.BDD; - } - ReportAggregates reportAggregates = new ReportAggregatesBuilder() - .setAuthorContext(authorContext) - .setCategoryContext(categoryContext) - .setDeviceContext(deviceContext) - .setExceptionContext(exceptionContextBuilder) - .setReportStatusStats(stats) - .setStatusCollection(statusSet) - .setSystemAttributeContext(systemAttributeContext) - .setTestList(testList) - .setTestRunnerLogs(testRunnerLogs) - .setStartTime(reportStartDate) - .setEndTime(reportEndDate) - .build(); - reporterList.forEach(x -> x.setAnalysisStrategy(strategy)); - reporterList.forEach(x -> x.flush(reportAggregates)); - } - - /** - * Ends logging, stops and clears the list of reporters - */ - protected void end() { - flush(); - reporterList.forEach(ExtentReporter::stop); - reporterList.clear(); - } - - /** - * Add a system attribute - * - * @param sa a {@link SystemAttribute} object - */ - protected void setSystemInfo(SystemAttribute sa) { - systemAttributeContext.setSystemAttribute(sa); - } - - /** - * Add a test runner log - * - * @param log a log event - */ - protected void setTestRunnerLogs(String log) { - testRunnerLogs.add(log); - } - - /** - * Updates the {@link AnalysisStrategy} - * - * @param strategy a {@link AnalysisStrategy} object - */ - protected void setAnalysisStrategy(AnalysisStrategy strategy) { - this.strategy = strategy; - stats = new ReportStatusStats(strategy); - } - - /** - * Setting to allow user driven configuration for test time-stamps - * - * @param useManualConfig setting for manual configuration - */ - protected void setAllowManualConfig(boolean useManualConfig) { - this.usesManualConfiguration = useManualConfig; - } - - /** - * Returns the current value of using manual configuration for test time-stamps - * - * @return setting for manual configuration - */ - protected boolean getAllowManualConfig() { - return usesManualConfiguration; - } - - /** - * Return the {@link ReportStatusStats} object - * - * @return a {@link ReportStatusStats} object - */ - protected ReportStatusStats getStats() { - generateRecentStatus(); - return stats; - } -} diff --git a/src/main/java/com/aventstack/extentreports/ExtentReporter.java b/src/main/java/com/aventstack/extentreports/ExtentReporter.java deleted file mode 100644 index ac5961c..0000000 --- a/src/main/java/com/aventstack/extentreports/ExtentReporter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aventstack.extentreports; - -/** - * Primary interface implemented by each reporter. This interface implements {@link TestListener} and - * {@link ReportAggregatesListener} interface to provide additional functionality to each reporter. - */ -public interface ExtentReporter - extends TestListener, AnalysisStrategyService { - - /** - * Starts passing run information to the reporter - */ - void start(); - - /** - * Stops the reporter. Ensures no information is passed to the reporter. - */ - void stop(); - - /** - * Write to or update the target source (file, database) - * - * @param reportAggregates a {@link ReportAggregates} object - */ - void flush(ReportAggregates reportAggregates); - - /** - * Get the reporter name - * - * @return reporter name - */ - String getReporterName(); -} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ExtentReports.java b/src/main/java/com/aventstack/extentreports/ExtentReports.java index 18e437c..0caf258 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentReports.java +++ b/src/main/java/com/aventstack/extentreports/ExtentReports.java @@ -7,16 +7,19 @@ import com.aventstack.extentreports.gherkin.GherkinDialectProvider; import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel; import com.aventstack.extentreports.model.SystemAttribute; +import com.aventstack.extentreports.reporter.ExtentReporter; /** *

    - * The ExtentReports report client for starting reporters and building reports. For most applications, - * you should have one ExtentReports instance for the entire JVM. + * The ExtentReports report client for starting reporters and building reports. + * For most applications, you should have one ExtentReports instance for the + * entire JVM. *

    * *

    - * ExtentReports itself does not build any reports, but allows reporters to access information, which in - * turn build the said reports. An example of building an HTML report and adding information to ExtentX: + * ExtentReports itself does not build any reports, but allows reporters to + * access information, which in turn build the said reports. An example of + * building an HTML report and adding information to ExtentX: *

    * *
    @@ -32,13 +35,14 @@
      * 
    * *

    - * A few notes: + * A few notes: *

    * *
      - *
    • It is mandatory to call the flush method to ensure information is written to the started - * reporters.
    • - *
    • You can create standard and BDD-style tests using the createTest method
    • + *
    • It is mandatory to call the flush method to ensure + * information is written to the started reporters.
    • + *
    • You can create standard and BDD-style tests using the + * createTest method
    • *
    * * @see ExtentTest @@ -46,358 +50,368 @@ * @see IGherkinFormatterModel * @see Status */ -public class ExtentReports - extends ExtentObservable { - - /** - * Attach a {@link ExtentReporter} reporter, allowing it to access all started tests, nodes and logs - * - *

    - * Available reporter types are: - *

    - * - *
      - *
    • ExtentHtmlReporter provided by artifactId "extent-html-formatter"
    • - *
    • ExtentEmailReporter (pro-only) provided by artifactId "extent-email-formatter"
    • - *
    • KlovReporter provided by artifactId "extent-klov-reporter"
    • - *
    • ConsoleLogger
    • - *
    - * - * @param reporter {@link ExtentReporter} reporter - */ - public void attachReporter(ExtentReporter... reporter) { - Arrays.stream(reporter).forEach(this::register); - } - - /** - * Returns a list of started reporters - * - * @return A list of {@link ExtentReporter} - */ - public List getStartedReporters() { - return getReporterCollection(); - } +public class ExtentReports extends ReportObservable { - /** - * Creates a BDD-style test with description representing one of the {@link IGherkinFormatterModel} - * classes such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * extent.createTest(Feature.class, "feature", "description");
    -     * extent.createTest(Scenario.class, "scenario", "description");
    -     * extent.createTest(Given.class, "given", "description");
    -     * 
    - * - * @param type A {@link IGherkinFormatterModel} type - * @param testName Name of test - * @param description A short description of the test - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createTest(Class type, String testName, String description) { - ExtentTest t = new ExtentTest(this, type, testName, description); - applyCommonTestSettings(t); - - saveTest(t.getModel()); - - return t; - } - - /** - * Creates a BDD-style test representing one of the {@link IGherkinFormatterModel} classes such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * extent.createTest(Feature.class, "feature");
    -     * extent.createTest(Scenario.class, "scenario");
    -     * extent.createTest(Given.class, "given");
    -     * 
    - * - * @param type A {@link IGherkinFormatterModel} type - * @param testName Name of test - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createTest(Class type, String testName) { - return createTest(type, testName, null); - } - - /** - * Creates a BDD-style test with description using name of the Gherkin model such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * extent.createTest(new GherkinKeyword("Feature"), "feature", "description");
    -     * extent.createTest(new GherkinKeyword("Scenario"), "scenario", "description");
    -     * extent.createTest(new GherkinKeyword("Given"), "given", "description");
    -     * 
    - * - * @param gherkinKeyword Name of the {@link GherkinKeyword} - * @param testName Name of test - * @param description A short description of the test - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createTest(GherkinKeyword gherkinKeyword, String testName, String description) { - Class clazz = gherkinKeyword.getKeyword().getClass(); - return createTest(clazz, testName, description); - } - - /** - * Creates a BDD-style test using name of the Gherkin model such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * extent.createTest(new GherkinKeyword("Feature"), "feature");
    -     * extent.createTest(new GherkinKeyword("Scenario"), "scenario");
    -     * extent.createTest(new GherkinKeyword("Given"), "given");
    -     * 
    - * - * @param gherkinKeyword Name of the {@link GherkinKeyword} - * @param testName Name of test - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createTest(GherkinKeyword gherkinKeyword, String testName) { - return createTest(gherkinKeyword, testName, null); - } - - /** - * Creates a test with description - * - * @param testName Name of test - * @param description A short test description - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createTest(String testName, String description) { - ExtentTest t = new ExtentTest(this, testName, description); - applyCommonTestSettings(t); - - saveTest(t.getModel()); - - return t; - } + /** + * Attach a {@link ExtentReporter} reporter, allowing it to access all started + * tests, nodes and logs + * + *

    + * Available reporter types are: + *

    + * + *
      + *
    • ExtentHtmlReporter provided by artifactId "extent-html-formatter"
    • + *
    • ExtentEmailReporter (pro-only) provided by artifactId + * "extent-email-formatter"
    • + *
    • KlovReporter provided by artifactId "extent-klov-reporter"
    • + *
    • ConsoleLogger
    • + *
    + * + * @param reporter {@link ExtentReporter} reporter + */ + public void attachReporter(ExtentReporter... reporter) { + Arrays.stream(reporter).forEach(this::register); + } + + /** + * Returns a list of started reporters + * + * @return A list of {@link ExtentReporter} + */ + public List getStartedReporters() { + return getReporterCollection(); + } + + /** + * Creates a BDD-style test with description representing one of the + * {@link IGherkinFormatterModel} classes such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * extent.createTest(Feature.class, "feature", "description");
    +	 * extent.createTest(Scenario.class, "scenario", "description");
    +	 * extent.createTest(Given.class, "given", "description");
    +	 * 
    + * + * @param type A {@link IGherkinFormatterModel} type + * @param testName Name of test + * @param description A short description of the test + * + * @return {@link ExtentTest} object + */ + public ExtentTest createTest(Class type, String testName, + String description) { + ExtentTest t = new ExtentTest(this, type, testName, description); + applyCommonTestSettings(t); + saveTest(t.getModel()); + return t; + } + + /** + * Creates a BDD-style test representing one of the + * {@link IGherkinFormatterModel} classes such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * extent.createTest(Feature.class, "feature");
    +	 * extent.createTest(Scenario.class, "scenario");
    +	 * extent.createTest(Given.class, "given");
    +	 * 
    + * + * @param type A {@link IGherkinFormatterModel} type + * @param testName Name of test + * + * @return {@link ExtentTest} object + */ + public ExtentTest createTest(Class type, String testName) { + return createTest(type, testName, null); + } + + /** + * Creates a BDD-style test with description using name of the Gherkin model + * such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * extent.createTest(new GherkinKeyword("Feature"), "feature", "description");
    +	 * extent.createTest(new GherkinKeyword("Scenario"), "scenario", "description");
    +	 * extent.createTest(new GherkinKeyword("Given"), "given", "description");
    +	 * 
    + * + * @param gherkinKeyword Name of the {@link GherkinKeyword} + * @param testName Name of test + * @param description A short description of the test + * + * @return {@link ExtentTest} object + */ + public ExtentTest createTest(GherkinKeyword gherkinKeyword, String testName, String description) { + Class clazz = gherkinKeyword.getKeyword().getClass(); + return createTest(clazz, testName, description); + } - /** - * Creates a test - * - * @param testName Name of test - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createTest(String testName) { - return createTest(testName, null); - } - - private synchronized void applyCommonTestSettings(ExtentTest extentTest) { - extentTest.setUseManualConfiguration(getAllowManualConfig()); - } - - /** - * Removes a test - * - * @param test {@link ExtentTest} object - */ - public synchronized void removeTest(ExtentTest test) { - super.removeTest(test.getModel()); - } - - /** - * Writes test information from the started reporters to their output view - * - *
      - *
    • extent-html-formatter: flush output to HTML file
    • - *
    • extent-klov-reporter: updates MongoDB collections
    • - *
    • extent-email-formatter (pro-only): creates or appends to an HTML file
    • - *
    • ConsoleLogger: no action taken
    • - *
    - */ - @Override - public synchronized void flush() { - super.flush(); - } + /** + * Creates a BDD-style test using name of the Gherkin model such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * extent.createTest(new GherkinKeyword("Feature"), "feature");
    +	 * extent.createTest(new GherkinKeyword("Scenario"), "scenario");
    +	 * extent.createTest(new GherkinKeyword("Given"), "given");
    +	 * 
    + * + * @param gherkinKeyword Name of the {@link GherkinKeyword} + * @param testName Name of test + * + * @return {@link ExtentTest} object + */ + public ExtentTest createTest(GherkinKeyword gherkinKeyword, String testName) { + return createTest(gherkinKeyword, testName, null); + } + + /** + * Creates a test with description + * + * @param testName Name of test + * @param description A short test description + * + * @return {@link ExtentTest} object + */ + public ExtentTest createTest(String testName, String description) { + ExtentTest t = new ExtentTest(this, testName, description); + applyCommonTestSettings(t); + + saveTest(t.getModel()); + + return t; + } - /** - * Adds any applicable system information to all started reporters - * - *

    - * Example: - *

    - * - *
    -     * extent.setSystemInfo("HostName", "AventStack-PC");
    -     * 
    - * - * @param k Name of system variable - * @param v Value of system variable - */ - public void setSystemInfo(String k, String v) { - SystemAttribute sa = new SystemAttribute(k, v); - super.setSystemInfo(sa); - } - - /** - * Adds logs from test framework tools to the test-runner logs view (if available in the reporter) - * - *

    - * TestNG usage example: - *

    - * - *
    -     * extent.setTestRunnerOutput(Reporter.getOutput());
    -     * 
    - * - * @param log Log string from the test runner frameworks such as TestNG or JUnit - */ - public void setTestRunnerOutput(List log) { - log.forEach(this::setTestRunnerLogs); - } - - /** - * Adds logs from test framework tools to the test-runner logs view (if available in the reporter) - * - *

    - * TestNG usage example: - *

    - * - *
    -     * for (String s : Reporter.getOutput()) {
    -     *   extent.setTestRunnerOutput(s);
    -     * }
    -     * 
    - * - * @param log Log string from the test runner frameworks such as TestNG or JUnit - */ - public void setTestRunnerOutput(String log) { - setTestRunnerLogs(log); - } - - /** - * Use this setting when building post-execution reports, such as from TestNG IReporter. - * This setting allows setting test with your own time-stamps. With this enabled, Extent - * does not use time-stamps for tests at the time they were created. - * - *

    - * If this setting is enabled and time-stamps are not specified explicitly, the time-stamps - * of test creation are used. - * - * @param useManualConfig Set to true if building reports at the end of execution with manual configuration - */ - public void setReportUsesManualConfiguration(boolean useManualConfig) { - setAllowManualConfig(useManualConfig); - } + /** + * Creates a test + * + * @param testName Name of test + * + * @return {@link ExtentTest} object + */ + public ExtentTest createTest(String testName) { + return createTest(testName, null); + } + + private void applyCommonTestSettings(ExtentTest extentTest) { + extentTest.setUseManualConfiguration(getAllowManualConfig()); + } + + /** + * Removes a test + * + * @param test {@link ExtentTest} object + */ + public void removeTest(ExtentTest test) { + super.removeTest(test.getModel()); + } /** - * Type of AnalysisStrategy for the reporter. Not all reporters support this setting. - * - *

    - * There are 2 types of strategies available: - * - *

      - *
    • TEST: Shows analysis at the test and step level
    • - *
    • SUITE: Shows analysis at the suite, test and step level
    • - *
    - * - * @param strategy {@link AnalysisStrategy} determines the type of analysis (dashboard) - * created for the reporter. Not all reporters will support this setting. - */ - @Override - public void setAnalysisStrategy(AnalysisStrategy strategy) { - super.setAnalysisStrategy(strategy); - } - - /** - * Provides common report configurations - * - * @return an instance of {@link ReportConfigurator} - */ - public ReportConfigurator config() { - return ReportConfigurator.getInstance(); - } - - /** - * Allows setting the target language for Gherkin keywords. - * - *

    - * Default setting is "en" - * - * @param language A valid dialect from - * gherkin-languages.json - * - * @throws UnsupportedEncodingException Thrown if the language is one of the supported language from - * gherkin-languages.json - */ - public void setGherkinDialect(String language) throws UnsupportedEncodingException { - GherkinDialectProvider.setLanguage(language); - } - - /** - * Returns an instance of {@link ReportStatusStats} with counts of tests executed - * by their status (pass, fail, skip etc) - * - * @return an instance of {@link ReportStatusStats} - */ - @Override - public ReportStatusStats getStats() { - return super.getStats(); - } - -} + * Writes test information from the started reporters to their output view + * + *

      + *
    • extent-html-formatter: flush output to HTML file
    • + *
    • extent-klov-reporter: updates MongoDB collections
    • + *
    • extent-email-formatter (pro-only): creates or appends to an HTML + * file
    • + *
    • ConsoleLogger: no action taken
    • + *
    + */ + @Override + public synchronized void flush() { + super.flush(); + } + + /** + * Adds any applicable system information to all started reporters + * + *

    + * Example: + *

    + * + *
    +	 * extent.setSystemInfo("HostName", "AventStack-PC");
    +	 * 
    + * + * @param k Name of system variable + * @param v Value of system variable + */ + public void setSystemInfo(String k, String v) { + SystemAttribute sa = new SystemAttribute(k, v); + super.setSystemInfo(sa); + } + + /** + * Adds logs from test framework tools to the test-runner logs view (if + * available in the reporter) + * + *

    + * TestNG usage example: + *

    + * + *
    +	 * extent.setTestRunnerOutput(Reporter.getOutput());
    +	 * 
    + * + * @param log Log string from the test runner frameworks such as TestNG or JUnit + */ + public void setTestRunnerOutput(List log) { + log.forEach(this::setTestRunnerLogs); + } + + /** + * Adds logs from test framework tools to the test-runner logs view (if + * available in the reporter) + * + *

    + * TestNG usage example: + *

    + * + *
    +	 * for (String s : Reporter.getOutput()) {
    +	 * 	extent.setTestRunnerOutput(s);
    +	 * }
    +	 * 
    + * + * @param log Log string from the test runner frameworks such as TestNG or JUnit + */ + public void setTestRunnerOutput(String log) { + setTestRunnerLogs(log); + } + + /** + * Use this setting when building post-execution reports, such as from TestNG + * IReporter. This setting allows setting test with your own time-stamps. With + * this enabled, Extent does not use time-stamps for tests at the time they were + * created. + * + *

    + * If this setting is enabled and time-stamps are not specified explicitly, the + * time-stamps of test creation are used. + * + * @param useManualConfig Set to true if building reports at the end of + * execution with manual configuration + */ + public void setReportUsesManualConfiguration(boolean useManualConfig) { + setAllowManualConfig(useManualConfig); + } + + /** + * Type of AnalysisStrategy for the reporter. Not all reporters support this + * setting. + * + *

    + * There are 2 types of strategies available: + * + *

      + *
    • TEST: Shows analysis at the test and step level
    • + *
    • SUITE: Shows analysis at the suite, test and step level
    • + *
    + * + * @param strategy {@link AnalysisStrategy} determines the type of analysis + * (dashboard) created for the reporter. Not all reporters will + * support this setting. + */ + @Override + public void setAnalysisStrategy(AnalysisStrategy strategy) { + super.setAnalysisStrategy(strategy); + } + + /** + * Provides common report configurations + * + * @return an instance of {@link ReportConfigurator} + */ + public ReportConfigurator config() { + return ReportConfigurator.getInstance(); + } + + /** + * Allows setting the target language for Gherkin keywords. + * + *

    + * Default setting is "en" + * + * @param language A valid dialect from gherkin-languages.json + * + * @throws UnsupportedEncodingException Thrown if the language is one of the + * supported language from gherkin-languages.json + */ + public void setGherkinDialect(String language) throws UnsupportedEncodingException { + GherkinDialectProvider.setLanguage(language); + } + + /** + * Returns an instance of {@link ReportStatusStats} with counts of tests + * executed by their status (pass, fail, skip etc) + * + * @return an instance of {@link ReportStatusStats} + */ + @Override + public ReportStatusStats getStats() { + return super.getStats(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ExtentTest.java b/src/main/java/com/aventstack/extentreports/ExtentTest.java index 7696a42..5aaf277 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentTest.java +++ b/src/main/java/com/aventstack/extentreports/ExtentTest.java @@ -10,17 +10,16 @@ import com.aventstack.extentreports.model.Category; import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.ExceptionInfo; -import com.aventstack.extentreports.model.IAddsMedia; import com.aventstack.extentreports.model.Log; import com.aventstack.extentreports.model.Media; -import com.aventstack.extentreports.model.MediaType; import com.aventstack.extentreports.model.ScreenCapture; -import com.aventstack.extentreports.model.Screencast; import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.utils.ExceptionUtil; import com.aventstack.extentreports.utils.StringUtil; /** - * Defines a test. You can add logs, snapshots, assign author and categories to a test and its children. + * Defines a test. You can add logs, snapshots, assign author and categories to + * a test and its children. * *

    * The below log types will all be logged with Status.PASS: @@ -37,1182 +36,1172 @@ *

    * *
      - *
    • Tests started with the createTest method are parent-level, always level 0
    • - *
    • Tests started with the createNode method are children, always level 1 and greater
    • + *
    • Tests started with the createTest method are parent-level, + * always level 0
    • + *
    • Tests started with the createNode method are children, + * always level 1 and greater
    • *
    */ -public class ExtentTest - implements IAddsMedia, RunResult, Serializable { - - private static final long serialVersionUID = 9199820968410788862L; - - /** - * An instance of {@link ExtentReports} to which this {@link ExtentTest} belongs - */ - private transient ExtentReports extent; - - /** - * Internal model - */ - private Test test; - - /** - * Creates a BDD style parent test representing one of the {@link IGherkinFormatterModel} - * classes. This method would ideally be used for creating the parent, ie {@link Feature). - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * extent.createTest(Feature.class, "Feature Name", "Description");
    -     * 
    - * - * @param extent An {@link ExtentReports} object - * @param type A {@link IGherkinFormatterModel} type - * @param testName Test name - * @param description Test description - */ - ExtentTest(ExtentReports extent, Class type, String testName, String description) { - if (testName == null || testName.isEmpty()) - throw new IllegalArgumentException("testName cannot be null or empty"); - - this.extent = extent; - - test = new Test(); - test.setName(testName.trim()); - test.setDescription(description == null ? "" : description.trim()); - - if (type != null) { - test.setBehaviorDrivenType(type); - } - } - - /** - * Create a test with description - * - * @param extent An {@link ExtentReports} object - * @param testName Test name - * @param description Test description - */ - ExtentTest(ExtentReports extent, String testName, String description) { - this(extent, null, testName, description); - } - - /** - * Creates a BDD-style node with description representing one of the {@link IGherkinFormatterModel} - * classes: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * test.createNode(Scenario.class, "bddNode", "description");
    -     * 
    - * - * @param type A {@link IGherkinFormatterModel} type - * @param name Name of node - * @param description A short description - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createNode(Class type, String name, String description) { - if (name == null || name.isEmpty()) - throw new IllegalArgumentException("nodeName cannot be null or empty"); - - ExtentTest t; - if (type == null) { - t = new ExtentTest(extent, name, description); - } else { - t = new ExtentTest(extent, type, name, description); - } - - applyCommonNodeSettings(t); - addNodeToReport(t); - return t; - } - - /** - * Creates a node with description - * - * @param name Name of node - * @param description A short description - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createNode(String name, String description) { - if (name == null || name.isEmpty()) - throw new IllegalArgumentException("nodeName cannot be null or empty"); - - ExtentTest t = new ExtentTest(extent, name, description); - applyCommonNodeSettings(t); - addNodeToReport(t); - return t; - } - - /** - * Creates a BDD-style node representing one of the {@link IGherkinFormatterModel} classes such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * test.createNode(Scenario.class, "bddNode");
    -     * 
    - * - * @param type A {@link IGherkinFormatterModel} type - * @param name Name of node - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createNode(Class type, String name) { - return createNode(type, name, null); - } - - /** - * Creates a BDD-style node with description using name of the Gherkin model such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * test.createNode(new GherkinKeyword("Scenario"), "bddTest", "description");
    -     * 
    - * - * @param gherkinKeyword Name of the {@link GherkinKeyword} - * @param name Name of node - * @param description A short description - * - * @return {@link ExtentTest} - */ - public synchronized ExtentTest createNode(GherkinKeyword gherkinKeyword, String name, String description) { - Class clazz = gherkinKeyword.getKeyword().getClass(); - return createNode(clazz, name, description); - } - - /** - * Creates a BDD-style node using name of the Gherkin model such as: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    - * - *

    - * Example: - *

    - * - *
    -     * test.createNode(new GherkinKeyword("Scenario"), "bddTest");
    -     * 
    - * - * @param gherkinKeyword Name of the {@link GherkinKeyword} - * @param name Name of node - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createNode(GherkinKeyword gherkinKeyword, String name) { - return createNode(gherkinKeyword, name, null); - } - - /** - * Creates a node - * - * @param name Name of node - * - * @return {@link ExtentTest} object - */ - public synchronized ExtentTest createNode(String name) { - return createNode(name, null); - } - - private void applyCommonNodeSettings(ExtentTest extentTest) { - extentTest.getModel().setLevel(test.getLevel() + 1); - extentTest.getModel().setParent(getModel()); - test.addChildNode(extentTest.getModel()); - } - - private void addNodeToReport(ExtentTest extentNode) { - extent.addNode(extentNode.getModel()); - } - - /** - * Logs an event with {@link Status}, details and a media object: {@link Screencast} or - * {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * test.log(Status.FAIL, "details", MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param status {@link Status} - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public synchronized ExtentTest log(Status status, String details, MediaEntityModelProvider provider) { - Log evt = createLog(status, details); - addMedia(evt, provider); - return addLog(evt); - } - - private synchronized void addMedia(Log evt, MediaEntityModelProvider provider) { - if (provider != null) { - Class clazz = provider.getMedia().getClass(); - - if (clazz.equals(ScreenCapture.class)) { - ScreenCapture sc = (ScreenCapture) provider.getMedia(); - evt.setScreenCapture(sc); - } else { - evt.setScreencast((Screencast) provider.getMedia()); - } - } - } - - /** - * Logs an event with {@link Status} and details - * - * @param status {@link Status} - * @param details Details - * - * @return An {@link ExtentTest} object - */ - public synchronized ExtentTest log(Status status, String details) { - return log(status, details, null); - } - - /** - * Logs an event with {@link Status} and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param status {@link Status} - * @param markup {@link Markup} - * - * @return An {@link ExtentTest} object - */ - public synchronized ExtentTest log(Status status, Markup markup) { - String details = markup.getMarkup(); - return log(status, details); - } - - private synchronized ExtentTest addLog(Log evt) { - test.getLogContext().add(evt); - test.end(); - - extent.addLog(test, evt); - - if (evt.hasScreenCapture()) { - try { - extent.addScreenCapture(evt, evt.getScreenCaptureContext().getLast()); - } catch (IOException e) { - e.printStackTrace(); - } - } - - return this; - } - - private Log createLog(Status status) { - Log evt = new Log(this); - evt.setStatus(status); - evt.setSequence(test.getLogContext().getAll().size() + 1); - return evt; - } - - private Log createLog(Status status, String details) { - Log evt = createLog(status); - evt.setDetails(details == null ? "" : details.trim()); - return evt; - } - - /** - * Logs an event with {@link Status}, an exception and a media object: {@link Screencast} or - * {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    -     * test.log(Status.FAIL, exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param status {@link Status} - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public synchronized ExtentTest log(Status status, Throwable t, MediaEntityModelProvider provider) { - ExceptionInfo exInfo = new ExceptionInfo(t); - getModel().setExceptionInfo(exInfo); - Log evt = createLog(status); - evt.setExceptionInfo(exInfo); - addMedia(evt, provider); - return addLog(evt); - } - - /** - * Logs an event with {@link Status} and exception - * - * @param status {@link Status} - * @param t {@link Throwable} - * - * @return An {@link ExtentTest} object - */ - public synchronized ExtentTest log(Status status, Throwable t) { - return log(status, t, null); - } - - /** - * Logs an Status.INFO event with details and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * test.info("details", MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest info(String details, MediaEntityModelProvider provider) { - log(Status.INFO, details, provider); - return this; - } - - /** - * Logs an event with Status.INFO with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest info(String details) { - return info(details, null); - } - - /** - * Logs an Status.INFO event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +public class ExtentTest implements IAddsMedia, RunResult, Serializable {
    +
    +	private static final long serialVersionUID = 9199820968410788862L;
    +
    +	/**
    +	 * An instance of {@link ExtentReports} to which this {@link ExtentTest} belongs
    +	 */
    +	private transient ExtentReports extent;
    +
    +	/**
    +	 * Internal model
    +	 */
    +	private Test test;
    +
    +	/**
    +	 * Creates a BDD style parent test representing one of the
    +	 * {@link IGherkinFormatterModel} classes. This method would ideally be used for
    +	 * creating the parent, ie {@link Feature).
    +	 * 
    +	 * 
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * extent.createTest(Feature.class, "Feature Name", "Description");
    +	 * 
    + * + * @param extent An {@link ExtentReports} object + * @param type A {@link IGherkinFormatterModel} type + * @param name Test name + * @param description Test description + */ + ExtentTest(ExtentReports extent, Class type, String name, String description) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("testName cannot be null or empty"); + } + this.extent = extent; + test = new Test(); + test.setName(name.trim()); + test.setDescription(description == null ? "" : description.trim()); + if (type != null) { + test.setBddType(type); + } + } + + /** + * Create a test with description + * + * @param extent An {@link ExtentReports} object + * @param testName Test name + * @param description Test description + */ + ExtentTest(ExtentReports extent, String testName, String description) { + this(extent, null, testName, description); + } + + /** + * Creates a BDD-style node with description representing one of the + * {@link IGherkinFormatterModel} classes: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * test.createNode(Scenario.class, "bddNode", "description");
    +	 * 
    + * + * @param type A {@link IGherkinFormatterModel} type + * @param name Name of node + * @param description A short description + * + * @return {@link ExtentTest} object + */ + public ExtentTest createNode(Class type, String name, String description) { + if (name == null || name.isEmpty()) + throw new IllegalArgumentException("nodeName cannot be null or empty"); + + ExtentTest t; + if (type == null) { + t = new ExtentTest(extent, name, description); + } else { + t = new ExtentTest(extent, type, name, description); + } + + applyCommonNodeSettings(t); + addNodeToReport(t); + return t; + } + + /** + * Creates a node with description + * + * @param name Name of node + * @param description A short description + * + * @return {@link ExtentTest} object + */ + public ExtentTest createNode(String name, String description) { + if (name == null || name.isEmpty()) + throw new IllegalArgumentException("nodeName cannot be null or empty"); + + ExtentTest t = new ExtentTest(extent, name, description); + applyCommonNodeSettings(t); + addNodeToReport(t); + return t; + } + + /** + * Creates a BDD-style node representing one of the + * {@link IGherkinFormatterModel} classes such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * test.createNode(Scenario.class, "bddNode");
    +	 * 
    + * + * @param type A {@link IGherkinFormatterModel} type + * @param name Name of node + * + * @return {@link ExtentTest} object + */ + public ExtentTest createNode(Class type, String name) { + return createNode(type, name, null); + } + + /** + * Creates a BDD-style node with description using name of the Gherkin model + * such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * test.createNode(new GherkinKeyword("Scenario"), "bddTest", "description");
    +	 * 
    + * + * @param gherkinKeyword Name of the {@link GherkinKeyword} + * @param name Name of node + * @param description A short description + * + * @return {@link ExtentTest} + */ + public ExtentTest createNode(GherkinKeyword gherkinKeyword, String name, String description) { + Class clazz = gherkinKeyword.getKeyword().getClass(); + return createNode(clazz, name, description); + } + + /** + * Creates a BDD-style node using name of the Gherkin model such as: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    + * + *

    + * Example: + *

    + * + *
    +	 * test.createNode(new GherkinKeyword("Scenario"), "bddTest");
    +	 * 
    + * + * @param gherkinKeyword Name of the {@link GherkinKeyword} + * @param name Name of node + * + * @return {@link ExtentTest} object + */ + public ExtentTest createNode(GherkinKeyword gherkinKeyword, String name) { + return createNode(gherkinKeyword, name, null); + } + + /** + * Creates a node + * + * @param name Name of node + * + * @return {@link ExtentTest} object + */ + public ExtentTest createNode(String name) { + return createNode(name, null); + } + + private void applyCommonNodeSettings(ExtentTest extentTest) { + extentTest.getModel().setLevel(test.getLevel() + 1); + extentTest.getModel().setParent(getModel()); + test.getNodeContext().add(extentTest.getModel()); + } + + private void addNodeToReport(ExtentTest extentNode) { + extent.addNode(extentNode.getModel()); + } + + /** + * Logs an event with {@link Status}, details and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * test.log(Status.FAIL, "details", MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    +	 * 
    + * + * @param status {@link Status} + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest log(Status status, String details, MediaEntityModelProvider provider) { + Log evt = createLog(status, details); + addMedia(evt, provider); + return addLog(evt); + } + + private void addMedia(Log evt, MediaEntityModelProvider provider) { + if (provider != null) { + Class clazz = provider.getMedia().getClass(); + + if (clazz.equals(ScreenCapture.class)) { + ScreenCapture c = (ScreenCapture) provider.getMedia(); + evt.getScreenCapture().add(c); + } else { + + } + } + } + + /** + * Logs an event with {@link Status} and details + * + * @param status {@link Status} + * @param details Details + * + * @return An {@link ExtentTest} object + */ + public ExtentTest log(Status status, String details) { + return log(status, details, null); + } + + /** + * Logs an event with {@link Status} and custom {@link Markup} such as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param status {@link Status} + * @param markup {@link Markup} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest log(Status status, Markup markup) { + String details = markup.getMarkup(); + return log(status, details); + } + + private ExtentTest addLog(Log evt) { + getModel().getLogContext().add(evt); + getModel().end(); + extent.addLog(getModel(), evt); + + if (!evt.getScreenCapture().isEmpty()) { + try { + extent.addScreenCapture(evt, evt.getScreenCapture().getLast()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return this; + } + + private Log createLog(Status status) { + Log evt = new Log(getModel()); + evt.setStatus(status); + evt.setSequence(test.getLogContext().size() + 1); + return evt; + } + + private Log createLog(Status status, String details) { + Log evt = createLog(status); + evt.setDetails(details == null ? "" : details.trim()); + return evt; + } + + /** + * Logs an event with {@link Status}, an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
    +	 * test.log(Status.FAIL, exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    +	 * 
    + * + * @param status {@link Status} + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest log(Status status, Throwable t, MediaEntityModelProvider provider) { + ExceptionInfo exceptionInfo = new ExceptionInfo(); + exceptionInfo.setThrowable(t); + exceptionInfo.setExceptionName(ExceptionUtil.getExceptionHeadline(t)); + exceptionInfo.setStackTrace(ExceptionUtil.getStackTrace(t)); + Log evt = createLog(status); + evt.setExceptionInfo(exceptionInfo); + addMedia(evt, provider); + return addLog(evt); + } + + /** + * Logs an event with {@link Status} and exception + * + * @param status {@link Status} + * @param t {@link Throwable} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest log(Status status, Throwable t) { + return log(status, t, null); + } + + /** + * Logs an Status.INFO event with details and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * test.info("details", MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    +	 * 
    + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest info(String details, MediaEntityModelProvider provider) { + log(Status.INFO, details, provider); + return this; + } + + /** + * Logs an event with Status.INFO with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest info(String details) { + return info(details, null); + } + + /** + * Logs an Status.INFO event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.info(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest info(Throwable t, MediaEntityModelProvider provider) { - log(Status.INFO, t, provider); - return this; - } - - /** - * Logs an event with Status.INFO and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest info(Throwable t) { - return info(t, null); - } - - /** - * Logs an event with Status.INFO and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return {@link ExtentTest} object - */ - public ExtentTest info(Markup m) { - log(Status.INFO, m); - return this; - } - - /** - * Logs an Status.PASS event with details and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * test.pass("details", MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest pass(String details, MediaEntityModelProvider provider) { - log(Status.PASS, details, provider); - return this; - } - - /** - * Logs an event Status.PASS with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest pass(String details) { - return pass(details, null); - } - - /** - * Logs an Status.PASS event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest info(Throwable t, MediaEntityModelProvider provider) { + log(Status.INFO, t, provider); + return this; + } + + /** + * Logs an event with Status.INFO and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest info(Throwable t) { + return info(t, null); + } + + /** + * Logs an event with Status.INFO and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return {@link ExtentTest} object + */ + public ExtentTest info(Markup m) { + log(Status.INFO, m); + return this; + } + + /** + * Logs an Status.PASS event with details and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * test.pass("details", MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    +	 * 
    + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest pass(String details, MediaEntityModelProvider provider) { + log(Status.PASS, details, provider); + return this; + } + + /** + * Logs an event Status.PASS with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest pass(String details) { + return pass(details, null); + } + + /** + * Logs an Status.PASS event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.pass(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest pass(Throwable t, MediaEntityModelProvider provider) { - log(Status.PASS, t, provider); - return this; - } - - /** - * Logs an event with Status.PASS and exception - * - * @param t {@link Throwable} - * - * @return An {@link ExtentTest} object - */ - public ExtentTest pass(Throwable t) { - return pass(t, null); - } - - /** - * Logs an event with Status.PASS and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return An {@link ExtentTest} object - */ - public ExtentTest pass(Markup m) { - log(Status.PASS, m); - return this; - } - - /** - * Logs an Status.FAIL event with details and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest fail(String details, MediaEntityModelProvider provider) { - log(Status.FAIL, details, provider); - return this; - } - - /** - * Logs an event Status.FAIL with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest fail(String details) { - return fail(details, null); - } - - /** - * Logs an Status.FAIL event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest pass(Throwable t, MediaEntityModelProvider provider) { + log(Status.PASS, t, provider); + return this; + } + + /** + * Logs an event with Status.PASS and exception + * + * @param t {@link Throwable} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest pass(Throwable t) { + return pass(t, null); + } + + /** + * Logs an event with Status.PASS and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest pass(Markup m) { + log(Status.PASS, m); + return this; + } + + /** + * Logs an Status.FAIL event with details and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest fail(String details, MediaEntityModelProvider provider) { + log(Status.FAIL, details, provider); + return this; + } + + /** + * Logs an event Status.FAIL with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest fail(String details) { + return fail(details, null); + } + + /** + * Logs an Status.FAIL event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.fail(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest fail(Throwable t, MediaEntityModelProvider provider) { - log(Status.FAIL, t, provider); - return this; - } - - /** - * Logs an event with Status.FAIL and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest fail(Throwable t) { - return fail(t, null); - } - - /** - * Logs an event with Status.FAIL and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return {@link ExtentTest} object - */ - public ExtentTest fail(Markup m) { - log(Status.FAIL, m); - return this; - } - - /** - * Logs an Status.DATAL event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest fatal(String details, MediaEntityModelProvider provider) { - log(Status.FATAL, details, provider); - return this; - } - - /** - * Logs an event Status.FATAL with details - * - * @param details Details - * - * @return An {@link ExtentTest} object - */ - public ExtentTest fatal(String details) { - log(Status.FATAL, details); - return this; - } - - /** - * Logs an Status.FATAL event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest fail(Throwable t, MediaEntityModelProvider provider) { + log(Status.FAIL, t, provider); + return this; + } + + /** + * Logs an event with Status.FAIL and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest fail(Throwable t) { + return fail(t, null); + } + + /** + * Logs an event with Status.FAIL and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return {@link ExtentTest} object + */ + public ExtentTest fail(Markup m) { + log(Status.FAIL, m); + return this; + } + + /** + * Logs an Status.DATAL event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest fatal(String details, MediaEntityModelProvider provider) { + log(Status.FATAL, details, provider); + return this; + } + + /** + * Logs an event Status.FATAL with details + * + * @param details Details + * + * @return An {@link ExtentTest} object + */ + public ExtentTest fatal(String details) { + log(Status.FATAL, details); + return this; + } + + /** + * Logs an Status.FATAL event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.fatal(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest fatal(Throwable t, MediaEntityModelProvider provider) { - log(Status.FATAL, t, provider); - return this; - } - - /** - * Logs an event with Status.FATAL and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest fatal(Throwable t) { - log(Status.FATAL, t); - return this; - } - - /** - * Logs an event with Status.FATAL and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return An {@link ExtentTest} object - */ - public ExtentTest fatal(Markup m) { - log(Status.FATAL, m); - return this; - } - - /** - * Logs an Status.WARNING event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest warning(String details, MediaEntityModelProvider provider) { - log(Status.WARNING, details, provider); - return this; - } - - /** - * Logs an event Status.WARNING with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest warning(String details) { - return warning(details, null); - } - - /** - * Logs an Status.WARNING event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest fatal(Throwable t, MediaEntityModelProvider provider) { + log(Status.FATAL, t, provider); + return this; + } + + /** + * Logs an event with Status.FATAL and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest fatal(Throwable t) { + log(Status.FATAL, t); + return this; + } + + /** + * Logs an event with Status.FATAL and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest fatal(Markup m) { + log(Status.FATAL, m); + return this; + } + + /** + * Logs an Status.WARNING event with an exception and a media + * object: {@link Screencast} or {@link ScreenCapture} + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest warning(String details, MediaEntityModelProvider provider) { + log(Status.WARNING, details, provider); + return this; + } + + /** + * Logs an event Status.WARNING with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest warning(String details) { + return warning(details, null); + } + + /** + * Logs an Status.WARNING event with an exception and a media + * object: {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.warning(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest warning(Throwable t, MediaEntityModelProvider provider) { - log(Status.WARNING, t, provider); - return this; - } - - /** - * Logs an event with Status.WARNING and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest warning(Throwable t) { - return warning(t, null); - } - - /** - * Logs an event with Status.WARNING and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return An {@link ExtentTest} object - */ - public ExtentTest warning(Markup m) { - log(Status.WARNING, m); - return this; - } - - /** - * Logs an Status.ERROR event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest error(String details, MediaEntityModelProvider provider) { - log(Status.ERROR, details, provider); - return this; - } - - /** - * Logs an event Status.ERROR with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest error(String details) { - return error(details, null); - } - - /** - * Logs an Status.ERROR event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest warning(Throwable t, MediaEntityModelProvider provider) { + log(Status.WARNING, t, provider); + return this; + } + + /** + * Logs an event with Status.WARNING and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest warning(Throwable t) { + return warning(t, null); + } + + /** + * Logs an event with Status.WARNING and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest warning(Markup m) { + log(Status.WARNING, m); + return this; + } + + /** + * Logs an Status.ERROR event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest error(String details, MediaEntityModelProvider provider) { + log(Status.ERROR, details, provider); + return this; + } + + /** + * Logs an event Status.ERROR with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest error(String details) { + return error(details, null); + } + + /** + * Logs an Status.ERROR event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.error(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest error(Throwable t, MediaEntityModelProvider provider) { - log(Status.ERROR, t, provider); - return this; - } - - /** - * Logs an event with Status.ERROR and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest error(Throwable t) { - return error(t, null); - } - - /** - * Logs an event with Status.ERROR and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return {@link ExtentTest} object - */ - public ExtentTest error(Markup m) { - log(Status.ERROR, m); - return this; - } - - /** - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest skip(String details, MediaEntityModelProvider provider) { - log(Status.SKIP, details, provider); - return this; - } - - /** - * Logs an event Status.SKIP with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest skip(String details) { - return skip(details, null); - } - - /** - * Logs an Status.SKIP event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest error(Throwable t, MediaEntityModelProvider provider) { + log(Status.ERROR, t, provider); + return this; + } + + /** + * Logs an event with Status.ERROR and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest error(Throwable t) { + return error(t, null); + } + + /** + * Logs an event with Status.ERROR and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return {@link ExtentTest} object + */ + public ExtentTest error(Markup m) { + log(Status.ERROR, m); + return this; + } + + /** + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest skip(String details, MediaEntityModelProvider provider) { + log(Status.SKIP, details, provider); + return this; + } + + /** + * Logs an event Status.SKIP with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest skip(String details) { + return skip(details, null); + } + + /** + * Logs an Status.SKIP event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
     	 * test.skip(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest skip(Throwable t, MediaEntityModelProvider provider) { - log(Status.SKIP, t, provider); - return this; - } - - /** - * Logs an event with Status.SKIP and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest skip(Throwable t) { - return skip(t, null); - } - - /** - * Logs an event with Status.SKIP and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return {@link ExtentTest} object - */ - public ExtentTest skip(Markup m) { - log(Status.SKIP, m); - return this; - } - - /** - * Logs an Status.DEBUG event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - * @param details Details - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest debug(String details, MediaEntityModelProvider provider) { - log(Status.DEBUG, details, provider); - return this; - } - - /** - * Logs an event Status.DEBUG with details - * - * @param details Details - * - * @return {@link ExtentTest} object - */ - public ExtentTest debug(String details) { - return debug(details, null); - } - - /** - * Logs an Status.DEBUG event with an exception and a media object: - * {@link Screencast} or {@link ScreenCapture} - * - *

    - * Example: - *

    - * - *
    -     * Exception exception = new NullPointerException();
    -     * test.debug(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    -     * 
    - * - * @param t {@link Throwable} - * @param provider A {@link MediaEntityModelProvider} object - * - * @return An {@link ExtentTest} object - */ - public ExtentTest debug(Throwable t, MediaEntityModelProvider provider) { - log(Status.DEBUG, t, provider); - return this; - } - - /** - * Logs an event with Status.SKIP and exception - * - * @param t {@link Throwable} - * - * @return {@link ExtentTest} object - */ - public ExtentTest debug(Throwable t) { - return debug(t, null); - } - - /** - * Logs an event with Status.DEBUG and custom {@link Markup} such as: - * - *
      - *
    • Code block
    • - *
    • Label
    • - *
    • Table
    • - *
    - * - * @param m {@link Markup} - * - * @return {@link ExtentTest} object - */ - public ExtentTest debug(Markup m) { - log(Status.DEBUG, m); - return this; - } - - /** - * Assigns a category or group - * - * @param category Category name - * - * @return {@link ExtentTest} object - */ - public ExtentTest assignCategory(String... category) { - if (category == null) - return this; - - Arrays.stream(category) - .filter(StringUtil::isNotNullOrEmpty) - .forEach(c -> { - Category objCategory = new Category(c.replace(" ", "")); - test.setCategory(objCategory); - extent.assignCategory(test, objCategory); - } - ); - return this; - } - - /** - * Assigns an author - * - * @param author Author name - * - * @return {@link ExtentTest} object - */ - public ExtentTest assignAuthor(String... author) { - Arrays.stream(author) - .filter(StringUtil::isNotNullOrEmpty) - .forEach(x -> { - Author a = new Author(x.replace(" ", "")); - test.setAuthor(a); - extent.assignAuthor(test, a); - } - ); - return this; - } - - /** - * Assign a device - * - * @param device Device name - * - * @return {@link ExtentTest} object - */ - public ExtentTest assignDevice(String... device) { - Arrays.stream(device) - .filter(StringUtil::isNotNullOrEmpty) - .forEach(x -> { - Device d = new Device(x.replace(" ", "")); - test.setDevice(d); - extent.assignDevice(test, d); - } - ); - return this; - } - - @Override - public ExtentTest addScreenCaptureFromPath(String imagePath, String title) throws IOException { - if (imagePath == null || imagePath.isEmpty()) - throw new IllegalArgumentException("imagePath cannot be null or empty"); - - ScreenCapture screenCapture = new ScreenCapture(); - screenCapture.setPath(imagePath); - if (title != null) { - screenCapture.setName(title); - } - screenCapture.setMediaType(MediaType.IMG); - if (test.getObjectId() != null) { - screenCapture.setTestObjectId(test.getObjectId()); - } - extent.addScreenCapture(test, screenCapture); - return addScreenCapture(screenCapture); - } - - private ExtentTest addScreenCapture(ScreenCapture screenCapture) { - test.setScreenCapture(screenCapture); - if (test.getObjectId() != null) { - int sequence = test.getScreenCaptureList().size(); - screenCapture.setTestObjectId(test.getObjectId()); - screenCapture.setSequence(sequence); - } - return this; - } - - @Override - public ExtentTest addScreenCaptureFromPath(String imagePath) throws IOException { - return addScreenCaptureFromPath(imagePath, null); - } - - @Override - public ExtentTest addScreenCaptureFromBase64String(String s, String title) { - ScreenCapture screenCapture = new ScreenCapture(); - screenCapture.setBase64String(s); - screenCapture.setName(title); - screenCapture.setMediaType(MediaType.IMG); - - if (test.getObjectId() != null) - screenCapture.setTestObjectId(test.getObjectId()); - - try { - extent.addScreenCapture(test, screenCapture); - } catch (IOException e) {} - - return addScreenCapture(screenCapture); - } - - @Override - public ExtentTest addScreenCaptureFromBase64String(String s) { - return addScreenCaptureFromBase64String(s, null); - } - - @Override - public ExtentTest addScreencastFromPath(String screencastPath) throws IOException { - Screencast screencast = new Screencast(); - screencast.setPath(screencastPath); - screencast.setMediaType(MediaType.VID); - test.setScreencast(screencast); - if (test.getObjectId() != null) { - int sequence = test.getScreencastList().size(); - screencast.setTestObjectId(test.getObjectId()); - screencast.setSequence(sequence); - } - extent.addScreencast(test, screencast); - return this; - } - - /** - * Provides the current run status of the test or node - * - * @return {@link Status} - */ - public Status getStatus() { - extent.generateRecentStatus(); - return getModel().getStatus(); - } - - /** - * Returns the underlying test which controls the internal model - * - * @return {@link Test} object - */ - public Test getModel() { - return test; - } - - /** - * Returns the {@link ExtentReports} instance associated with this test - * - * @return the {@link ExtentReports} instance associated with this test - */ - public ExtentReports getExtent() { - return extent; - } - - void setUseManualConfiguration(Boolean b) { - getModel().setUseManualConfiguration(b); - } + *
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest skip(Throwable t, MediaEntityModelProvider provider) { + log(Status.SKIP, t, provider); + return this; + } + + /** + * Logs an event with Status.SKIP and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest skip(Throwable t) { + return skip(t, null); + } + + /** + * Logs an event with Status.SKIP and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return {@link ExtentTest} object + */ + public ExtentTest skip(Markup m) { + log(Status.SKIP, m); + return this; + } + + /** + * Logs an Status.DEBUG event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + * @param details Details + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest debug(String details, MediaEntityModelProvider provider) { + log(Status.DEBUG, details, provider); + return this; + } + + /** + * Logs an event Status.DEBUG with details + * + * @param details Details + * + * @return {@link ExtentTest} object + */ + public ExtentTest debug(String details) { + return debug(details, null); + } + + /** + * Logs an Status.DEBUG event with an exception and a media object: + * {@link Screencast} or {@link ScreenCapture} + * + *

    + * Example: + *

    + * + *
    +	 * Exception exception = new NullPointerException();
    +	 * test.debug(exception, MediaEntityBuilder.createScreenCaptureFromPath("screen.png").build());
    +	 * 
    + * + * @param t {@link Throwable} + * @param provider A {@link MediaEntityModelProvider} object + * + * @return An {@link ExtentTest} object + */ + public ExtentTest debug(Throwable t, MediaEntityModelProvider provider) { + log(Status.DEBUG, t, provider); + return this; + } + + /** + * Logs an event with Status.SKIP and exception + * + * @param t {@link Throwable} + * + * @return {@link ExtentTest} object + */ + public ExtentTest debug(Throwable t) { + return debug(t, null); + } + + /** + * Logs an event with Status.DEBUG and custom {@link Markup} such + * as: + * + *
      + *
    • Code block
    • + *
    • Label
    • + *
    • Table
    • + *
    + * + * @param m {@link Markup} + * + * @return {@link ExtentTest} object + */ + public ExtentTest debug(Markup m) { + log(Status.DEBUG, m); + return this; + } + + /** + * Assigns a category or group + * + * @param category Category name + * + * @return {@link ExtentTest} object + */ + public ExtentTest assignCategory(String... category) { + if (category == null) { + return this; + } + Arrays.stream(category).filter(StringUtil::isNotNullOrEmpty).forEach(c -> { + Category cat = new Category(c.replace(" ", "")); + test.getCategoryContext().add(cat); + extent.assignCategory(test, cat); + }); + return this; + } + + /** + * Assigns an author + * + * @param author Author name + * + * @return {@link ExtentTest} object + */ + public ExtentTest assignAuthor(String... author) { + Arrays.stream(author).filter(StringUtil::isNotNullOrEmpty).forEach(x -> { + Author a = new Author(x.replace(" ", "")); + test.getAuthorContext().add(a); + extent.assignAuthor(test, a); + }); + return this; + } + + /** + * Assign a device + * + * @param device Device name + * + * @return {@link ExtentTest} object + */ + public ExtentTest assignDevice(String... device) { + Arrays.stream(device).filter(StringUtil::isNotNullOrEmpty).forEach(x -> { + Device d = new Device(x.replace(" ", "")); + test.getDeviceContext().add(d); + extent.assignDevice(test, d); + }); + return this; + } + + @Override + public ExtentTest addScreenCaptureFromPath(String imagePath, String title) throws IOException { + if (imagePath == null || imagePath.isEmpty()) + throw new IllegalArgumentException("imagePath cannot be null or empty"); + + ScreenCapture screenCapture = new ScreenCapture(); + screenCapture.setPath(imagePath); + if (title != null) { + screenCapture.setName(title); + } + /* + * if (test.getObjectId() != null) { + * screenCapture.setTestObjectId(test.getObjectId()); } + */ + extent.addScreenCapture(test, screenCapture); + return addScreenCapture(screenCapture); + } + + private ExtentTest addScreenCapture(ScreenCapture screenCapture) { + test.getScreenCaptureContext().add(screenCapture); + /* + * if (test.getObjectId() != null) { int sequence = + * test.getScreenCaptureList().size(); + * screenCapture.setTestObjectId(test.getObjectId()); + * screenCapture.setSequence(sequence); } + */ + return this; + } + + @Override + public ExtentTest addScreenCaptureFromPath(String imagePath) throws IOException { + return addScreenCaptureFromPath(imagePath, null); + } + + @Override + public ExtentTest addScreenCaptureFromBase64String(String s, String title) { + ScreenCapture screenCapture = new ScreenCapture(); + screenCapture.setBase64String(s); + screenCapture.setName(title); + + /* + * if (test.getObjectId() != null) + * screenCapture.setTestObjectId(test.getObjectId()); + */ + + try { + extent.addScreenCapture(test, screenCapture); + } catch (IOException e) { + } + + return addScreenCapture(screenCapture); + } + + @Override + public ExtentTest addScreenCaptureFromBase64String(String s) { + return addScreenCaptureFromBase64String(s, null); + } + + /** + * Provides the current run status of the test or node + * + * @return {@link Status} + */ + public Status getStatus() { + extent.generateRecentStatus(); + return getModel().getStatus(); + } + + /** + * Returns the underlying test which controls the internal model + * + * @return {@link Test} object + */ + public Test getModel() { + return test; + } + + /** + * Returns the {@link ExtentReports} instance associated with this test + * + * @return the {@link ExtentReports} instance associated with this test + */ + public ExtentReports getExtent() { + return extent; + } + + void setUseManualConfiguration(Boolean b) { + getModel().setUsesManualConfiguration(b); + } } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/GherkinKeyword.java b/src/main/java/com/aventstack/extentreports/GherkinKeyword.java index 49a2d53..f61ca5e 100644 --- a/src/main/java/com/aventstack/extentreports/GherkinKeyword.java +++ b/src/main/java/com/aventstack/extentreports/GherkinKeyword.java @@ -6,7 +6,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.aventstack.extentreports.exceptions.GherkinKeywordNotFoundException; import com.aventstack.extentreports.gherkin.GherkinDialect; import com.aventstack.extentreports.gherkin.GherkinDialectProvider; import com.aventstack.extentreports.gherkin.model.Asterisk; @@ -15,16 +14,18 @@ import freemarker.template.utility.StringUtil; /** - * Allows {@link IGherkinFormatterModel} to be returned by using a name, from the below gherkin model classes: + * Allows {@link IGherkinFormatterModel} to be returned by using a name, from + * the below gherkin model classes: * *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • *
    * *

    @@ -41,46 +42,46 @@ public class GherkinKeyword { private static final Logger logger = Logger.getLogger(GherkinKeyword.class.getName()); - - private Class clazz = IGherkinFormatterModel.class; - private IGherkinFormatterModel keywordClazz; - - public GherkinKeyword(String keyword) throws ClassNotFoundException { - GherkinDialect dialect = null; - String apiKeyword = StringUtil.capitalize(keyword.trim()); - String refPath = clazz.getPackage().getName(); - - try { - apiKeyword = apiKeyword.equals("*") ? Asterisk.class.getSimpleName() : apiKeyword; - dialect = GherkinDialectProvider.getDialect(); - if (dialect != null && !dialect.getLanguage().equalsIgnoreCase(GherkinDialectProvider.getDefaultLanguage())) { - apiKeyword = null; - Map> keywords = dialect.getKeywords(); - - for (Entry> key : keywords.entrySet()) { - boolean keywordLocated = key.getValue() - .stream() - .anyMatch(x -> x.trim().equalsIgnoreCase(keyword.trim())); - if (keywordLocated) { - apiKeyword = StringUtil.capitalize(key.getKey()); - break; - } - } - } - - if (apiKeyword == null) { - throw new GherkinKeywordNotFoundException("Keyword " + apiKeyword + " cannot be null"); - } - - String clazzName = refPath + "." + apiKeyword.replace(" ", ""); - Class c = Class.forName(clazzName); - keywordClazz = (IGherkinFormatterModel) c.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - logger.log(Level.SEVERE, "", e); - } - } - - IGherkinFormatterModel getKeyword() { - return keywordClazz; - } -} + + private Class clazz = IGherkinFormatterModel.class; + private IGherkinFormatterModel keywordClazz; + + public GherkinKeyword(String keyword) throws ClassNotFoundException { + GherkinDialect dialect = null; + String apiKeyword = StringUtil.capitalize(keyword.trim()); + String refPath = clazz.getPackage().getName(); + + try { + apiKeyword = apiKeyword.equals("*") ? Asterisk.class.getSimpleName() : apiKeyword; + dialect = GherkinDialectProvider.getDialect(); + if (dialect != null + && !dialect.getLanguage().equalsIgnoreCase(GherkinDialectProvider.getDefaultLanguage())) { + apiKeyword = null; + Map> keywords = dialect.getKeywords(); + + for (Entry> key : keywords.entrySet()) { + boolean keywordLocated = key.getValue().stream() + .anyMatch(x -> x.trim().equalsIgnoreCase(keyword.trim())); + if (keywordLocated) { + apiKeyword = StringUtil.capitalize(key.getKey()); + break; + } + } + } + + if (apiKeyword == null) { + throw new GherkinKeywordNotFoundException("Keyword " + apiKeyword + " cannot be null"); + } + + String clazzName = refPath + "." + apiKeyword.replace(" ", ""); + Class c = Class.forName(clazzName); + keywordClazz = (IGherkinFormatterModel) c.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + logger.log(Level.SEVERE, "", e); + } + } + + IGherkinFormatterModel getKeyword() { + return keywordClazz; + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/exceptions/GherkinKeywordNotFoundException.java b/src/main/java/com/aventstack/extentreports/GherkinKeywordNotFoundException.java similarity index 53% rename from src/main/java/com/aventstack/extentreports/exceptions/GherkinKeywordNotFoundException.java rename to src/main/java/com/aventstack/extentreports/GherkinKeywordNotFoundException.java index 2e623a3..198412f 100644 --- a/src/main/java/com/aventstack/extentreports/exceptions/GherkinKeywordNotFoundException.java +++ b/src/main/java/com/aventstack/extentreports/GherkinKeywordNotFoundException.java @@ -1,12 +1,11 @@ -package com.aventstack.extentreports.exceptions; +package com.aventstack.extentreports; -public class GherkinKeywordNotFoundException - extends ClassNotFoundException { +public class GherkinKeywordNotFoundException extends ClassNotFoundException { private static final long serialVersionUID = 3140022717738862603L; public GherkinKeywordNotFoundException(String message) { super(message); } - -} + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/IAddsMedia.java b/src/main/java/com/aventstack/extentreports/IAddsMedia.java new file mode 100644 index 0000000..9945ea8 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/IAddsMedia.java @@ -0,0 +1,55 @@ +package com.aventstack.extentreports; + +import java.io.IOException; + +public interface IAddsMedia { + + /** + * Adds a snapshot to the test or log with title + * + * @param mediaPath Image path + * @param title Image title + * + * @return Object this method is called from, generally + * {@link com.aventstack.extentreports.ExtentTest} or {@link Log} + * + * @throws IOException thrown if the imagePath of image is not + * found + */ + T addScreenCaptureFromPath(String mediaPath, String title) throws IOException; + + /** + * Adds a snapshot to test or log + * + * @param mediaPath Image path + * + * @return Object this method is called from, generally + * {@link com.aventstack.extentreports.ExtentTest} or {@link Log} + * + * @throws IOException thrown if the imagePath of image is not + * found + */ + T addScreenCaptureFromPath(String mediaPath) throws IOException; + + /** + * Adds a base64 screenshot + * + * @param base64 base64 string + * @param title Image title + * + * @return Object this method is called from, generally + * {@link com.aventstack.extentreports.ExtentTest} or {@link Log} + */ + T addScreenCaptureFromBase64String(String base64, String title); + + /** + * Adds a base64 screenshot + * + * @param base64 base64 string + * + * @return Object this method is called from, generally + * {@link com.aventstack.extentreports.ExtentTest} or {@link Log} + */ + T addScreenCaptureFromBase64String(String base64); + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/AnalysisStrategyService.java b/src/main/java/com/aventstack/extentreports/IAnalysisStrategyMethod.java similarity index 83% rename from src/main/java/com/aventstack/extentreports/AnalysisStrategyService.java rename to src/main/java/com/aventstack/extentreports/IAnalysisStrategyMethod.java index c89664f..4a92a99 100644 --- a/src/main/java/com/aventstack/extentreports/AnalysisStrategyService.java +++ b/src/main/java/com/aventstack/extentreports/IAnalysisStrategyMethod.java @@ -4,10 +4,10 @@ * Marker interface for a class that uses an {@link AnalysisStrategy} * */ -public interface AnalysisStrategyService { +public interface IAnalysisStrategyMethod { void setAnalysisStrategy(AnalysisStrategy strategy); AnalysisStrategy getAnalysisStrategy(); -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/exceptions/InvalidAnalysisStrategyException.java b/src/main/java/com/aventstack/extentreports/InvalidAnalysisStrategyException.java similarity index 81% rename from src/main/java/com/aventstack/extentreports/exceptions/InvalidAnalysisStrategyException.java rename to src/main/java/com/aventstack/extentreports/InvalidAnalysisStrategyException.java index dabf365..4ab1c81 100644 --- a/src/main/java/com/aventstack/extentreports/exceptions/InvalidAnalysisStrategyException.java +++ b/src/main/java/com/aventstack/extentreports/InvalidAnalysisStrategyException.java @@ -1,4 +1,4 @@ -package com.aventstack.extentreports.exceptions; +package com.aventstack.extentreports; public class InvalidAnalysisStrategyException extends IllegalArgumentException { @@ -7,5 +7,5 @@ public class InvalidAnalysisStrategyException extends IllegalArgumentException { public InvalidAnalysisStrategyException(String message) { super(message); } - -} + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/Main.java b/src/main/java/com/aventstack/extentreports/Main.java new file mode 100644 index 0000000..352e4e8 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/Main.java @@ -0,0 +1,45 @@ +package com.aventstack.extentreports; + +import java.io.File; +import java.io.IOException; + +import com.aventstack.extentreports.convert.TestModelReportBuilder; +import com.aventstack.extentreports.gherkin.model.Feature; +import com.aventstack.extentreports.gherkin.model.Given; +import com.aventstack.extentreports.gherkin.model.Scenario; +import com.aventstack.extentreports.gherkin.model.Then; +import com.aventstack.extentreports.gherkin.model.When; +import com.aventstack.extentreports.reporter.ExtentHtmlReporter; +import com.aventstack.extentreports.reporter.ExtentSparkReporter; + +public class Main { + + public static void main(String[] args) throws IOException { + ExtentSparkReporter spark = new ExtentSparkReporter("target/spark/"); + ExtentHtmlReporter html = new ExtentHtmlReporter("target/spark/html.html"); + ExtentReports extent = new ExtentReports(); + TestModelReportBuilder modelBuilder = new TestModelReportBuilder(); + modelBuilder.recreateModelFromJson(extent, new File("target/spark/test.json")); + extent.attachReporter(spark, html); + //JsonFormatter json = new JsonFormatter("target/spark/test.json"); + //extent.attachReporter(json); + + ExtentTest feature = extent.createTest(Feature.class, "My feature"); + ExtentTest scenario = feature.createNode(Scenario.class, "My scenario"); + scenario.createNode(Given.class, "Given something").pass(""); + scenario.createNode(When.class, "When I").pass(""); + scenario.createNode(Then.class, "Then something").pass(""); + + extent.flush(); + + /* + extent.createTest("FirstTest").pass("Passed"); + extent.createTest("SecondTest").createNode("SecondTestNode").warning("warn"); + extent.createTest("ThirdTest").createNode("ThirdTestNode").createNode("ThirdTestNodeNode").fail("fail"); + extent.createTest("CategoryTest").assignCategory("Cat").pass("Pass"); + extent.createTest("CategoryNodeTest").createNode("CategoryNode").assignCategory("ChildCat").skip("skip"); + */ + extent.flush(); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/MediaEntityBuilder.java b/src/main/java/com/aventstack/extentreports/MediaEntityBuilder.java index 7c11ca6..e008747 100644 --- a/src/main/java/com/aventstack/extentreports/MediaEntityBuilder.java +++ b/src/main/java/com/aventstack/extentreports/MediaEntityBuilder.java @@ -3,7 +3,6 @@ import java.io.IOException; import com.aventstack.extentreports.model.Media; -import com.aventstack.extentreports.model.MediaType; import com.aventstack.extentreports.model.ScreenCapture; /** @@ -13,55 +12,59 @@ public class MediaEntityBuilder { private static ThreadLocal media = new ThreadLocal<>(); - + private static class MediaBuilderInstance { - static final MediaEntityBuilder INSTANCE = new MediaEntityBuilder(); - - private MediaBuilderInstance() { } - } - - private MediaEntityBuilder() { } - - private static synchronized MediaEntityBuilder getInstance() { - return MediaBuilderInstance.INSTANCE; - } - + static final MediaEntityBuilder INSTANCE = new MediaEntityBuilder(); + + private MediaBuilderInstance() { + } + } + + private MediaEntityBuilder() { + } + + private static synchronized MediaEntityBuilder getInstance() { + return MediaBuilderInstance.INSTANCE; + } + public MediaEntityModelProvider build() { return new MediaEntityModelProvider(media.get()); } - - public static synchronized MediaEntityBuilder createScreenCaptureFromPath(String path, String title) throws IOException { - if (path == null || path.isEmpty()) - throw new IOException("ScreenCapture path cannot be null or empty."); - - return createScreenCapture(path, title, false); - } - - public static synchronized MediaEntityBuilder createScreenCaptureFromPath(String path) throws IOException { - return createScreenCaptureFromPath(path, null); - } - - public static synchronized MediaEntityBuilder createScreenCaptureFromBase64String(String base64String) throws IOException { - if (base64String == null || base64String.trim().equals("")) - throw new IOException("Base64 string cannot be null or empty."); - - return createScreenCapture(base64String, null, true); - } - - private static synchronized MediaEntityBuilder createScreenCapture(String pathOrBase64String, String title, boolean isBase64String) { - ScreenCapture sc = new ScreenCapture(); - sc.setMediaType(MediaType.IMG); - if (isBase64String) - sc.setBase64String(pathOrBase64String); - else - sc.setPath(pathOrBase64String); - - if (title != null) - sc.setName(title); - - media.set(sc); - - return getInstance(); - } - -} + + public static synchronized MediaEntityBuilder createScreenCaptureFromPath(String path, String title) + throws IOException { + if (path == null || path.isEmpty()) + throw new IOException("ScreenCapture path cannot be null or empty."); + + return createScreenCapture(path, title, false); + } + + public static synchronized MediaEntityBuilder createScreenCaptureFromPath(String path) throws IOException { + return createScreenCaptureFromPath(path, null); + } + + public static synchronized MediaEntityBuilder createScreenCaptureFromBase64String(String base64String) + throws IOException { + if (base64String == null || base64String.trim().equals("")) + throw new IOException("Base64 string cannot be null or empty."); + + return createScreenCapture(base64String, null, true); + } + + private static synchronized MediaEntityBuilder createScreenCapture(String pathOrBase64String, String title, + boolean isBase64String) { + ScreenCapture sc = new ScreenCapture(); + if (isBase64String) + sc.setBase64String(pathOrBase64String); + else + sc.setPath(pathOrBase64String); + + if (title != null) + sc.setName(title); + + media.set(sc); + + return getInstance(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/MediaEntityModelProvider.java b/src/main/java/com/aventstack/extentreports/MediaEntityModelProvider.java index 3b2f290..ef13f46 100644 --- a/src/main/java/com/aventstack/extentreports/MediaEntityModelProvider.java +++ b/src/main/java/com/aventstack/extentreports/MediaEntityModelProvider.java @@ -2,10 +2,6 @@ import com.aventstack.extentreports.model.Media; -/** - * Media singleton - * - */ public class MediaEntityModelProvider { private Media m; @@ -18,4 +14,4 @@ public Media getMedia() { return m; } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportAggregates.java b/src/main/java/com/aventstack/extentreports/ReportAggregates.java index ad15bdc..e1558f2 100644 --- a/src/main/java/com/aventstack/extentreports/ReportAggregates.java +++ b/src/main/java/com/aventstack/extentreports/ReportAggregates.java @@ -8,6 +8,9 @@ import com.aventstack.extentreports.model.Category; import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.ExceptionTestContextStore; +import com.aventstack.extentreports.model.context.SystemAttributeContext; +import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; /** * Aggregator for report elements and collections @@ -17,16 +20,16 @@ public class ReportAggregates { private List testList; private List testRunnerLogs; - private TestAttributeTestContextProvider categoryContext; - private TestAttributeTestContextProvider authorContext; - private TestAttributeTestContextProvider deviceContext; - private ExceptionTestContextImpl exceptionContext; + private TestAttributeTestContextStore categoryContext; + private TestAttributeTestContextStore authorContext; + private TestAttributeTestContextStore deviceContext; + private ExceptionTestContextStore exceptionContext; private SystemAttributeContext systemAttributeContext; private ReportStatusStats reportStatusStats; private Collection statusCollection; private Date startTime; private Date endTime; - + public Date getStartTime() { return startTime; } @@ -63,35 +66,35 @@ public void setTestRunnerLogs(List testRunnerLogs) { this.testRunnerLogs = testRunnerLogs; } - public TestAttributeTestContextProvider getCategoryContext() { + public TestAttributeTestContextStore getCategoryContext() { return categoryContext; } - public void setCategoryContext(TestAttributeTestContextProvider categoryContext) { + public void setCategoryContext(TestAttributeTestContextStore categoryContext) { this.categoryContext = categoryContext; } - public TestAttributeTestContextProvider getAuthorContext() { + public TestAttributeTestContextStore getAuthorContext() { return authorContext; } - public void setAuthorContext(TestAttributeTestContextProvider authorContext) { + public void setAuthorContext(TestAttributeTestContextStore authorContext) { this.authorContext = authorContext; } - public TestAttributeTestContextProvider getDeviceContext() { + public TestAttributeTestContextStore getDeviceContext() { return deviceContext; } - public void setDeviceContext(TestAttributeTestContextProvider deviceContext) { + public void setDeviceContext(TestAttributeTestContextStore deviceContext) { this.deviceContext = deviceContext; } - public ExceptionTestContextImpl getExceptionContext() { + public ExceptionTestContextStore getExceptionContext() { return exceptionContext; } - public void setExceptionContext(ExceptionTestContextImpl exceptionContext) { + public void setExceptionContext(ExceptionTestContextStore exceptionContext) { this.exceptionContext = exceptionContext; } @@ -119,4 +122,4 @@ public void setStatusCollection(Collection statusCollection) { this.statusCollection = statusCollection; } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java b/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java index a7a07d5..bea527a 100644 --- a/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java +++ b/src/main/java/com/aventstack/extentreports/ReportAggregatesBuilder.java @@ -8,6 +8,9 @@ import com.aventstack.extentreports.model.Category; import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.ExceptionTestContextStore; +import com.aventstack.extentreports.model.context.SystemAttributeContext; +import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; /** * Builds {@link ReportAggregates} @@ -17,29 +20,29 @@ public class ReportAggregatesBuilder { private List testList; private List testRunnerLogs; - private TestAttributeTestContextProvider categoryContext; - private TestAttributeTestContextProvider authorContext; - private TestAttributeTestContextProvider deviceContext; - private ExceptionTestContextImpl exceptionContext; + private TestAttributeTestContextStore categoryContext; + private TestAttributeTestContextStore authorContext; + private TestAttributeTestContextStore deviceContext; + private ExceptionTestContextStore exceptionContext; private SystemAttributeContext systemAttributeContext; private ReportStatusStats reportStatusStats; private Collection statusCollection; private Date startTime; private Date endTime; - + public ReportAggregates build() { - ReportAggregates aggregates = new ReportAggregates(); - aggregates.setTestList(testList); - aggregates.setTestRunnerLogs(testRunnerLogs); - aggregates.setCategoryContext(categoryContext); - aggregates.setAuthorContext(authorContext); - aggregates.setDeviceContext(deviceContext); - aggregates.setExceptionContext(exceptionContext); - aggregates.setSystemAttributeContext(systemAttributeContext); - aggregates.setReportStatusStats(reportStatusStats); - aggregates.setStatusCollection(statusCollection); - aggregates.setStartTime(startTime); - aggregates.setEndTime(endTime); + ReportAggregates aggregates = new ReportAggregates(); + aggregates.setTestList(testList); + aggregates.setTestRunnerLogs(testRunnerLogs); + aggregates.setCategoryContext(categoryContext); + aggregates.setAuthorContext(authorContext); + aggregates.setDeviceContext(deviceContext); + aggregates.setExceptionContext(exceptionContext); + aggregates.setSystemAttributeContext(systemAttributeContext); + aggregates.setReportStatusStats(reportStatusStats); + aggregates.setStatusCollection(statusCollection); + aggregates.setStartTime(startTime); + aggregates.setEndTime(endTime); return aggregates; } @@ -53,22 +56,22 @@ public ReportAggregatesBuilder setTestRunnerLogs(List testRunnerLogs) { return this; } - public ReportAggregatesBuilder setCategoryContext(TestAttributeTestContextProvider categoryContext) { + public ReportAggregatesBuilder setCategoryContext(TestAttributeTestContextStore categoryContext) { this.categoryContext = categoryContext; return this; } - public ReportAggregatesBuilder setAuthorContext(TestAttributeTestContextProvider authorContext) { + public ReportAggregatesBuilder setAuthorContext(TestAttributeTestContextStore authorContext) { this.authorContext = authorContext; return this; } - public ReportAggregatesBuilder setDeviceContext(TestAttributeTestContextProvider deviceContext) { + public ReportAggregatesBuilder setDeviceContext(TestAttributeTestContextStore deviceContext) { this.deviceContext = deviceContext; return this; } - public ReportAggregatesBuilder setExceptionContext(ExceptionTestContextImpl exceptionContext) { + public ReportAggregatesBuilder setExceptionContext(ExceptionTestContextStore exceptionContext) { this.exceptionContext = exceptionContext; return this; } @@ -88,14 +91,14 @@ public ReportAggregatesBuilder setStatusCollection(Collection statusColl return this; } - public ReportAggregatesBuilder setStartTime(Date startTime) { - this.startTime = startTime; - return this; - } - - public ReportAggregatesBuilder setEndTime(Date endTime) { - this.endTime = endTime; - return this; - } - -} + public ReportAggregatesBuilder setStartTime(Date startTime) { + this.startTime = startTime; + return this; + } + + public ReportAggregatesBuilder setEndTime(Date endTime) { + this.endTime = endTime; + return this; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportAggregatesListener.java b/src/main/java/com/aventstack/extentreports/ReportAggregatesListener.java index 6a6319f..a49863c 100644 --- a/src/main/java/com/aventstack/extentreports/ReportAggregatesListener.java +++ b/src/main/java/com/aventstack/extentreports/ReportAggregatesListener.java @@ -6,88 +6,97 @@ import com.aventstack.extentreports.model.Category; import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.ExceptionTestContextStore; +import com.aventstack.extentreports.model.context.SystemAttributeContext; +import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; /** - * Allows sharing of aggregates/collections to be shared with the started reporter. A few examples - * of these collections include: + * Allows sharing of aggregates/collections to be shared with the started + * reporter. A few examples of these collections include: * *

      - *
    • Category context - list of all categories and associated tests
    • - *
    • Exception context - list of all exceptions and associated tests
    • - *
    • Complete list of started tests
    • - *
    • System information
    • + *
    • Category context - list of all categories and associated tests
    • + *
    • Exception context - list of all exceptions and associated tests
    • + *
    • Complete list of started tests
    • + *
    • System information
    • *
    */ public interface ReportAggregatesListener { - - /** - * Allows sharing the complete list of tests with the reporter - * - * @param testList list of all tests created by {@link ExtentReports} - */ - void setTestList(List testList); - - /** - * Passes the complete list of logs to the reporter - * - * @param logs testrunner logs - */ - void setTestRunnerLogs(List logs); - - /** - * Allows sharing the complete list of category and associated tests with the reporter - * - * @param categoryContext collection containing categories and all associated tests - */ - void setCategoryContextInfo(TestAttributeTestContextProvider categoryContext); - /** - * Allows sharing the complete list of author and associated tests with the reporter - * - * @param authorContext collection containing author and all associated tests - */ - void setAuthorContextInfo(TestAttributeTestContextProvider authorContext); - - /** - * Allows sharing the complete list of device and associated tests with the reporter - * - * @param deviceContext collection containing devices and all associated tests - */ - void setDeviceContextInfo(TestAttributeTestContextProvider deviceContext); - - - /** - * Allows sharing the complete list of exceptions and associated tests with the reporter - * - * @param exceptionContext collection containing exception and all associated tests - */ - void setExceptionContextInfo(ExceptionTestContextImpl exceptionContext); - - /** - * Passes all system information to the reporter - * - * @param systemAttributeContext system information - */ - void setSystemAttributeContext(SystemAttributeContext systemAttributeContext); - - /** - * Report Status stats of the run session for all possible levels: - * - *
      - *
    • Features/Tests
    • - *
    • Scenarios/Logs
    • - *
    • Steps
    • - *
    - * - * @param sc {@link ReportStatusStats} represents stats of each hierarchical level of test/event - */ - void setReportStatusStats(ReportStatusStats sc); - - /** - * A distinct list of status assigned to tests - * - * @param statusList a distinct list of {@link Status} - */ - void setStatusList(List statusList); - -} + /** + * Allows sharing the complete list of tests with the reporter + * + * @param testList list of all tests created by {@link ExtentReports} + */ + void setTestList(List testList); + + /** + * Passes the complete list of logs to the reporter + * + * @param logs testrunner logs + */ + void setTestRunnerLogs(List logs); + + /** + * Allows sharing the complete list of category and associated tests with the + * reporter + * + * @param categoryContext collection containing categories and all associated + * tests + */ + void setCategoryContextInfo(TestAttributeTestContextStore categoryContext); + + /** + * Allows sharing the complete list of author and associated tests with the + * reporter + * + * @param authorContext collection containing author and all associated tests + */ + void setAuthorContextInfo(TestAttributeTestContextStore authorContext); + + /** + * Allows sharing the complete list of device and associated tests with the + * reporter + * + * @param deviceContext collection containing devices and all associated tests + */ + void setDeviceContextInfo(TestAttributeTestContextStore deviceContext); + + /** + * Allows sharing the complete list of exceptions and associated tests with the + * reporter + * + * @param exceptionContext collection containing exception and all associated + * tests + */ + void setExceptionContextInfo(ExceptionTestContextStore exceptionContext); + + /** + * Passes all system information to the reporter + * + * @param systemAttributeContext system information + */ + void setSystemAttributeContext(SystemAttributeContext systemAttributeContext); + + /** + * Report Status stats of the run session for all possible levels: + * + *
      + *
    • Features/Tests
    • + *
    • Scenarios/Logs
    • + *
    • Steps
    • + *
    + * + * @param sc {@link ReportStatusStats} represents stats of each hierarchical + * level of test/event + */ + void setReportStatusStats(ReportStatusStats sc); + + /** + * A distinct list of status assigned to tests + * + * @param statusList a distinct list of {@link Status} + */ + void setStatusList(List statusList); + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportConfigurator.java b/src/main/java/com/aventstack/extentreports/ReportConfigurator.java index 6443523..3469eaf 100644 --- a/src/main/java/com/aventstack/extentreports/ReportConfigurator.java +++ b/src/main/java/com/aventstack/extentreports/ReportConfigurator.java @@ -2,20 +2,22 @@ public class ReportConfigurator { - private static class ReportConfiguratorInstance { - static final ReportConfigurator INSTANCE = new ReportConfigurator(); - - private ReportConfiguratorInstance() { } - } + private static class ReportConfiguratorInstance { + static final ReportConfigurator INSTANCE = new ReportConfigurator(); - private ReportConfigurator() { } - - public static ReportConfigurator getInstance() { - return ReportConfiguratorInstance.INSTANCE; - } + private ReportConfiguratorInstance() { + } + } + + private ReportConfigurator() { + } + + public static ReportConfigurator getInstance() { + return ReportConfiguratorInstance.INSTANCE; + } + + public StatusConfigurator statusConfigurator() { + return StatusConfigurator.getInstance(); + } - public StatusConfigurator statusConfigurator() { - return StatusConfigurator.getInstance(); - } - } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportObservable.java b/src/main/java/com/aventstack/extentreports/ReportObservable.java new file mode 100644 index 0000000..878c892 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/ReportObservable.java @@ -0,0 +1,574 @@ +package com.aventstack.extentreports; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.aventstack.extentreports.model.Author; +import com.aventstack.extentreports.model.Category; +import com.aventstack.extentreports.model.Device; +import com.aventstack.extentreports.model.Log; +import com.aventstack.extentreports.model.ScreenCapture; +import com.aventstack.extentreports.model.SystemAttribute; +import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.ExceptionTestContextStore; +import com.aventstack.extentreports.model.context.SystemAttributeContext; +import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; +import com.aventstack.extentreports.model.context.helpers.TestRemover; +import com.aventstack.extentreports.model.service.TestService; +import com.aventstack.extentreports.reporter.BasicFileReporter; +import com.aventstack.extentreports.reporter.ExtentReporter; + +abstract class ReportObservable implements ReportService { + + /** + * The current AnalysisStrategy for the run session. This decides the technique + * used to count the test status at differing levels. For example, for a BDD + * style report, the levels to be calculated are Feature, Scenario and Step (3 + * levels). For a generic, non-BDD style report, levels can be dynamic. For a + * non-BDD style report, levels typically consist of: + * + *

    + * 1 level: Test
    + * Test
    + * - Event + * + *

    + * 2 levels: Test & node
    + * Test
    + * - Node
    + * -- Event + * + *

    + * 2 levels: Test, the leaf-node
    + * Test
    + * - Node
    + * -- Leaf Node
    + * --- Event + * + */ + private AnalysisStrategy strategy = AnalysisStrategy.TEST; + + /** + * Use this setting when building post-execution reports, such as from TestNG + * IReporter. This setting allows setting test with your own variables and + * prevent update by Extent. As of today, with this enabled, Extent does not use + * time-stamps for tests at the time they were created + */ + private boolean usesManualConfiguration = false; + + /** + * The status of the entire report or build + */ + private Status reportStatus = Status.PASS; + + /** + * Time the report or build was started + */ + private Date reportStartDate = Calendar.getInstance().getTime(); + + /** + * Time the report or build ended. This value is updated everytime + * flush is called + */ + private Date reportEndDate; + + /** + * A collection of tests arranged by category + */ + private TestAttributeTestContextStore categoryContext = new TestAttributeTestContextStore<>(); + + /** + * A collection of tests arranged by author + */ + private TestAttributeTestContextStore authorContext = new TestAttributeTestContextStore<>(); + + /** + * A collection of tests arranged by author + */ + private TestAttributeTestContextStore deviceContext = new TestAttributeTestContextStore<>(); + + /** + * A collection of tests arranged by exception + */ + private ExceptionTestContextStore exceptionContextBuilder = new ExceptionTestContextStore(); + + /** + * A context of all system or environment variables + */ + private SystemAttributeContext systemAttributeContext = new SystemAttributeContext(); + + /** + * A list of all {@link ExtentReporter} reporters started by the + * attachReporter method + */ + private List reporterList = new ArrayList<>(); + + /** + * Any logs added by to the test runner can be added to Extent + * + *

    + * TestNG Example: + * + *

    + * Setting logs with TestNG: + * + *

    +	 * Reporter.log("hello world")
    +	 * 
    + * + *

    + * Informing Extent of any logs added: + * + *

    +	 * for (String s : Reporter.getOutput()) {
    +	 * 	extent.setTestRunnerOutput(s);
    +	 * }
    +	 * 
    + */ + private List testRunnerLogs = new ArrayList<>(); + + /** + * A list of all tests created + */ + private List testList = new ArrayList<>(); + + /** + * Instance of {@link ReportStatusStats} + */ + private ReportStatusStats stats = new ReportStatusStats(strategy); + + /** + * A unique collection of statuses tests are marked with + * + *

    + * Consider a report having 10 tests: + * + *

      + *
    1. Test1: PASS
    2. + *
    3. Test2: PASS
    4. + *
    5. Test3: PASS
    6. + *
    7. Test4: SKIP
    8. + *
    9. Test5: SKIP
    10. + *
    11. Test6: FAIL
    12. + *
    13. Test7: PASS
    14. + *
    15. Test8: PASS
    16. + *
    17. Test9: FAIL
    18. + *
    19. Test10: PASS
    20. + *
    + * + *

    + * Distinct list of contained status: + * + *

      + *
    1. PASS
    2. + *
    3. SKIP
    4. + *
    5. FAIL
    6. + *
    + */ + private Set statusSet = new HashSet(); + + protected ReportObservable() { + } + + /** + * Subscribe the reporter to receive updates when making calls to the API + * + * @param reporter {@link ExtentReporter} reporter + */ + protected void register(ExtentReporter reporter) { + reporterList.add(reporter); + reporter.start(); + } + + /** + * Unsubscribe the reporter. Calling unsubscribe will call the stop + * method and also remove the reporter from the list of started reporters + * + * @param reporter {@link ExtentReporter} reporter to unsubscribe + */ + protected void deregister(ExtentReporter reporter) { + + if (reporterList.contains((Object) reporter)) { + reporter.stop(); + reporterList.remove(reporter); + } + } + + /** + * Retrieve a list of all started reporters + * + * @return a list of {@link ExtentReporter} objects + */ + protected List getReporterCollection() { + return reporterList; + } + + /** + * Saves the started test and notifies all started reporters + * + * @param test a {@link Test} object + */ + protected synchronized void saveTest(Test test) { + testList.add(test); + reporterList.forEach(x -> x.onTestStarted(test)); + } + + /** + * Removes the test and notifies all started reporters + * + * @param test a {@link Test} object + */ + protected void removeTest(Test test) { + removeTestTestList(test); + removeTestTestAttributeContext(test); + reporterList.forEach(x -> x.onTestRemoved(test)); + } + + /** + * Removes a test from test list + * + * @param test a {@link Test} object + */ + private void removeTestTestList(Test test) { + TestRemover.remove(testList, test); + refreshReportEntities(); + } + + /** + * Removes test from test list of each context + * + * @param test a {@link Test} object + */ + private void removeTestTestAttributeContext(Test test) { + if (TestService.testHasCategory(test)) { + categoryContext.removeTest(test); + } + if (TestService.testHasAuthor(test)) { + authorContext.removeTest(test); + } + if (TestService.testHasDevice(test)) { + deviceContext.removeTest(test); + } + } + + /** + * Refreshes report entities such as {@link ReportStatusStats} and list of + * distinct {@link Status} + */ + private void refreshReportEntities() { + refreshReportStats(); + refreshStatusList(); + } + + /** + * Refresh and notify all reports of {@link ReportStatusStats} + */ + private void refreshReportStats() { + stats.refresh(testList); + } + + /** + * Refresh and notify all reports of distinct status assigned to tests + */ + private synchronized void refreshStatusList() { + statusSet.clear(); + refreshStatusList(testList); + } + + /** + * Refreshes distinct status list + * + * @param list a list of started {@link Test} + */ + private synchronized void refreshStatusList(List list) { + if (list == null || list.isEmpty()) { + return; + } + list.forEach(x -> statusSet.add(x.getStatus())); + list.forEach(x -> refreshStatusList(x.getNodeContext().getAll())); + } + + /** + * Notify reporters of the added node + * + * @param node a {@link Test} node + */ + void addNode(Test node) { + reporterList.forEach(x -> x.onNodeStarted(node)); + } + + /** + * Notifies reporters with information of added {@link Log} + * + * @param test {@link Test} to which the event is added + * @param log {@link Log} + */ + void addLog(Test test, Log log) { + reporterList.forEach(x -> x.onLogAdded(test, log)); + } + + /** + * Notifies reporters with information of added {@link Category} + * + * @param test {@link Test} to which the Category is added + * @param category {@link Category} + */ + void assignCategory(Test test, Category category) { + reporterList.forEach(x -> x.onCategoryAssigned(test, category)); + } + + /** + * Notifies reporters with information of added {@link Author} + * + * @param test {@link Test} to which the Author is added + * @param author {@link Author} + */ + void assignAuthor(Test test, Author author) { + reporterList.forEach(x -> x.onAuthorAssigned(test, author)); + } + + /** + * Notifies reporters with information of added {@link Author} + * + * @param test {@link Test} to which the Device is added + * @param device {@link Device} + */ + void assignDevice(Test test, Device device) { + reporterList.forEach(x -> x.onDeviceAssigned(test, device)); + } + + /** + * Notifies reporters with information of added {@link ScreenCapture} + * + * @param test {@link Test} to which the ScreenCapture is added + * @param screenCapture {@link ScreenCapture} + * + * @throws IOException thrown if the {@link ScreenCapture} is not found + */ + void addScreenCapture(Test test, ScreenCapture screenCapture) throws IOException { + for (ExtentReporter r : reporterList) { + r.onScreenCaptureAdded(test, screenCapture); + } + } + + /** + * Notifies reporters with information of added {@link ScreenCapture} + * + * @param test {@link Log} to which the ScreenCapture is added + * @param screenCapture {@link ScreenCapture} + * + * @throws IOException thrown if the {@link ScreenCapture} is not found + */ + void addScreenCapture(Log log, ScreenCapture screenCapture) throws IOException { + for (ExtentReporter r : reporterList) { + r.onScreenCaptureAdded(log, screenCapture); + } + } + + /** + * Returns the context of author with the list of tests for each + * + * @return a {@link TestAttributeTestContextStore} object + */ + protected TestAttributeTestContextStore getAuthorContextInfo() { + return authorContext; + } + + /** + * Updates the status of the report or build + * + * @param status a {@link Status} + */ + private void updateReportStatus(Status status) { + int statusIndex = Status.getStatusHierarchy().indexOf(status); + int reportStatusIndex = Status.getStatusHierarchy().indexOf(reportStatus); + + reportStatus = statusIndex < reportStatusIndex ? status : reportStatus; + } + + /** + * Ends the test + * + * @param test a {@link Test} object + */ + private void endTest(Test test) { + test.end(); + updateReportStatus(test.getStatus()); + } + + /** + * Collects and updates all run information and notifies all reporters. + * Depending upon the type of reporter, additional events can occur such as: + * + *
      + *
    • A file written to disk (eg. case of {@link BasicFileReporter}
    • + *
    • A database being updated (eg. case of KlovReporter)
    • + *
    + */ + protected void flush() { + generateRecentStatus(); + notifyReporters(); + } + + /** + * Collects run information from all tests for assigned {@link Category}, + * {@link Author}, Exception, Nodes. This also ends and updates all internal + * test information and refreshes {@link ReportStatusStats} and the distinct + * list of {@link Status} + */ + public synchronized void generateRecentStatus() { + if (testList == null || testList.isEmpty()) + return; + + reportEndDate = Calendar.getInstance().getTime(); + refreshReportEntities(); + + for (Test test : testList) { + endTest(test); + test.setUsesManualConfiguration(getAllowManualConfig()); + if (TestService.testHasCategory(test)) { + test.getCategoryContext().getAll().forEach(x -> categoryContext.setAttributeContext((Category) x, test)); + } + if (TestService.testHasAuthor(test)) { + test.getAuthorContext().getAll().forEach(x -> authorContext.setAttributeContext((Author) x, test)); + } + if (TestService.testHasDevice(test)) { + test.getDeviceContext().getAll().forEach(x -> deviceContext.setAttributeContext((Device) x, test)); + } + if (TestService.testHasException(test)) { + test.getExceptionInfoContext().getAll().forEach(x -> exceptionContextBuilder.setExceptionContext(x, test)); + } + if (TestService.testHasChildren(test)) { + for (Test node : test.getNodeContext().getAll()) { + copyNodeAttributeAndRunTimeInfoToAttributeContexts(node); + node.setUsesManualConfiguration(getAllowManualConfig()); + } + } + } + + updateReportStartTimeForManualConfigurationSetting(); + } + + /** + * In case where manual configuration is used, calculate the correct timestamps + * based upon the timestamps assigned to tests + */ + private void updateReportStartTimeForManualConfigurationSetting() { + if (getAllowManualConfig() && !testList.isEmpty()) { + Date minDate = testList.stream().map(t -> t.getStartTime()).min(Date::compareTo).get(); + Date maxDate = testList.stream().map(t -> t.getEndTime()).max(Date::compareTo).get(); + reportStartDate = reportStartDate.getTime() > minDate.getTime() ? minDate : reportStartDate; + reportEndDate = reportEndDate.getTime() < maxDate.getTime() ? maxDate : reportEndDate; + } + } + + /** + * Traverse all nodes and refresh {@link Category}, {@link Author}, Exception + * and Node context information + * + * @param node a {@link Test} node + */ + private void copyNodeAttributeAndRunTimeInfoToAttributeContexts(Test node) { + if (TestService.testHasCategory(node)) { + node.getCategoryContext().getAll().forEach(x -> categoryContext.setAttributeContext((Category) x, node)); + } + if (TestService.testHasAuthor(node)) { + node.getAuthorContext().getAll().forEach(x -> authorContext.setAttributeContext((Author) x, node)); + } + if (TestService.testHasDevice(node)) { + node.getDeviceContext().getAll().forEach(x -> deviceContext.setAttributeContext((Device) x, node)); + } + if (TestService.testHasException(node)) { + node.getExceptionInfoContext().getAll().forEach(x -> exceptionContextBuilder.setExceptionContext(x, node)); + } + if (TestService.testHasChildren(node)) { + node.getNodeContext().getAll().forEach(this::copyNodeAttributeAndRunTimeInfoToAttributeContexts); + } + } + + /** + * Notify all reporters with complete run information + */ + private synchronized void notifyReporters() { + if (!testList.isEmpty() && TestService.isTestBehaviorDriven(testList.get(0))) { + strategy = AnalysisStrategy.BDD; + } + ReportAggregates reportAggregates = new ReportAggregatesBuilder().setAuthorContext(authorContext) + .setCategoryContext(categoryContext).setDeviceContext(deviceContext) + .setExceptionContext(exceptionContextBuilder).setReportStatusStats(stats).setStatusCollection(statusSet) + .setSystemAttributeContext(systemAttributeContext).setTestList(testList) + .setTestRunnerLogs(testRunnerLogs).setStartTime(reportStartDate).setEndTime(reportEndDate).build(); + reporterList.forEach(x -> x.setAnalysisStrategy(strategy)); + reporterList.forEach(x -> x.flush(reportAggregates)); + } + + /** + * Ends logging, stops and clears the list of reporters + */ + protected void end() { + flush(); + reporterList.forEach(ExtentReporter::stop); + reporterList.clear(); + } + + /** + * Add a system attribute + * + * @param sa a {@link SystemAttribute} object + */ + protected void setSystemInfo(SystemAttribute sa) { + systemAttributeContext.setSystemAttribute(sa); + } + + /** + * Add a test runner log + * + * @param log a log event + */ + protected void setTestRunnerLogs(String log) { + testRunnerLogs.add(log); + } + + /** + * Updates the {@link AnalysisStrategy} + * + * @param strategy a {@link AnalysisStrategy} object + */ + protected void setAnalysisStrategy(AnalysisStrategy strategy) { + this.strategy = strategy; + stats = new ReportStatusStats(strategy); + } + + /** + * Setting to allow user driven configuration for test time-stamps + * + * @param useManualConfig setting for manual configuration + */ + protected void setAllowManualConfig(boolean useManualConfig) { + this.usesManualConfiguration = useManualConfig; + } + + /** + * Returns the current value of using manual configuration for test time-stamps + * + * @return setting for manual configuration + */ + protected boolean getAllowManualConfig() { + return usesManualConfiguration; + } + + /** + * Return the {@link ReportStatusStats} object + * + * @return a {@link ReportStatusStats} object + */ + protected ReportStatusStats getStats() { + generateRecentStatus(); + return stats; + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportService.java b/src/main/java/com/aventstack/extentreports/ReportService.java index 048e690..2932d67 100644 --- a/src/main/java/com/aventstack/extentreports/ReportService.java +++ b/src/main/java/com/aventstack/extentreports/ReportService.java @@ -1,14 +1,16 @@ package com.aventstack.extentreports; import com.aventstack.extentreports.reporter.AbstractReporter; +import com.aventstack.extentreports.reporter.ExtentReporter; /** - * The main service for {@link ExtentReports} which allows attaching a reporter of type - * {@link AbstractReporter} + * The main service for {@link ExtentReports} which allows attaching a reporter + * of type {@link AbstractReporter} */ public interface ReportService { - + void attachReporter(ExtentReporter... reporter); + void generateRecentStatus(); - -} + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/ReportStatusStats.java b/src/main/java/com/aventstack/extentreports/ReportStatusStats.java index 017dd2c..cc9403b 100644 --- a/src/main/java/com/aventstack/extentreports/ReportStatusStats.java +++ b/src/main/java/com/aventstack/extentreports/ReportStatusStats.java @@ -2,386 +2,468 @@ import java.util.List; -import com.aventstack.extentreports.exceptions.InvalidAnalysisStrategyException; import com.aventstack.extentreports.gherkin.model.Scenario; import com.aventstack.extentreports.model.Test; /** *

    - * This class maintains the total count of tests and its nodes along with - * their statuses for a given run session + * This class maintains the total count of tests and its nodes along with their + * statuses for a given run session */ public class ReportStatusStats { - - private List testList; - private AnalysisStrategy strategy = AnalysisStrategy.TEST; - - private int parentPass = 0; - private int parentFail = 0; - private int parentFatal = 0; - private int parentError = 0; - private int parentWarning = 0; - private int parentSkip = 0; - private int parentExceptions = 0; - - private int childPass = 0; - private int childFail = 0; - private int childFatal = 0; - private int childError = 0; - private int childWarning = 0; - private int childSkip = 0; - private int childInfo = 0; - private int childDebug = 0; - private int childExceptions = 0; - - private int grandChildPass = 0; - private int grandChildFail = 0; - private int grandChildFatal = 0; - private int grandChildError = 0; - private int grandChildWarning = 0; - private int grandChildSkip = 0; - private int grandChildInfo = 0; - private int grandChildDebug = 0; - private int grandChildExceptions = 0; - - public ReportStatusStats(AnalysisStrategy strategy) { - this.strategy = strategy; - } - - public void refresh(List testList) { - reset(); - this.testList = testList; - refreshStats(); - } - - private void reset() { - parentPass = 0; - parentFail = 0; - parentFatal = 0; - parentError = 0; - parentWarning = 0; - parentSkip = 0; - parentExceptions = 0; - - childPass = 0; - childFail = 0; - childFatal = 0; - childError = 0; - childWarning = 0; - childSkip = 0; - childInfo = 0; - childExceptions = 0; - - grandChildPass = 0; - grandChildFail = 0; - grandChildFatal = 0; - grandChildError = 0; - grandChildWarning = 0; - grandChildSkip = 0; - grandChildInfo = 0; - grandChildExceptions = 0; - } - - public int getParentCount() { - return getParentCountPass() + - getParentCountFail() + - getParentCountFatal() + - getParentCountError() + - getParentCountWarning() + - getParentCountSkip(); - } - public int getParentCountPass() { return parentPass; } - public int getParentCountFail() { return parentFail; } - public int getParentCountFatal() { return parentFatal; } - public int getParentCountError() { return parentError; } - public int getParentCountWarning() { return parentWarning; } - public int getParentCountSkip() { return parentSkip; } - public int getParentCountExceptions() { return parentExceptions; } - - public float getParentPercentagePass() { - float p = getParentCount() > 0 ? (float)getParentCountPass()/(float)getParentCount() : 0; - return p*100; - } - public float getParentPercentageFail() { - float p = getParentCount() > 0 ? ((float)getParentCountFail()+(float)getParentCountFatal())/(float)getParentCount() : 0; - return p*100; - } - public float getParentPercentageOthers() { - float p = getParentCount() > 0 ? ((float)getParentCountWarning()+(float)getParentCountError())/(float)getParentCount() : 0; - return p*100; - } - public float getParentPercentageSkip() { - float p = getParentCount() > 0 ? (float)getParentCountSkip()/(float)getParentCount() : 0; - return p*100; - } - - public int getChildCount() { - return getChildCountPass() + - getChildCountFail() + - getChildCountFatal() + - getChildCountError() + - getChildCountWarning() + - getChildCountSkip() + - getChildCountInfo(); - } - public int getChildCountPass() { return childPass; } - public int getChildCountFail() { return childFail; } - public int getChildCountFatal() { return childFatal; } - public int getChildCountError() { return childError; } - public int getChildCountWarning() { return childWarning; } - public int getChildCountSkip() { return childSkip; } - public int getChildCountInfo() { return childInfo; } - public int getChildCountDebug() { return childDebug; } - public int getChildCountExceptions() { return childExceptions; } - - public float getChildPercentagePass() { - float p = getChildCount() > 0 ? (float)getChildCountPass()/(float)getChildCount() : 0; - return p*100; - } - public float getChildPercentageFail() { - float p = getChildCount() > 0 ? ((float)getChildCountFail()+(float)getChildCountFatal())/(float)getChildCount() : 0; - return p*100; - } - public float getChildPercentageOthers() { - float p = getChildCount() > 0 ? (((float)getChildCountWarning()+(float)getChildCountError()+(float)getChildCountSkip()+(float)getChildCountInfo())/(float)getChildCount()) : 0; - return p*100; - } - public float getChildPercentageSkip() { - float p = getChildCount() > 0 ? (float)getChildCountSkip()/(float)getChildCount() : 0; - return p*100; - } - - public int getGrandChildCount() { - return getGrandChildCountPass() + - getGrandChildCountFail() + - getGrandChildCountFatal() + - getGrandChildCountError() + - getGrandChildCountWarning() + - getGrandChildCountSkip() + - getGrandChildCountInfo(); - } - public int getGrandChildCountPass() { return grandChildPass; } - public int getGrandChildCountFail() { return grandChildFail; } - public int getGrandChildCountFatal() { return grandChildFatal; } - public int getGrandChildCountError() { return grandChildError; } - public int getGrandChildCountWarning() { return grandChildWarning; } - public int getGrandChildCountSkip() { return grandChildSkip; } - public int getGrandChildCountInfo() { return grandChildInfo; } - public int getGrandChildCountDebug() { return grandChildDebug; } - public int getGrandChildCountExceptions() { return grandChildExceptions; } - - public float getGrandChildPercentagePass() { - float p = getGrandChildCount() > 0 ? (float)getGrandChildCountPass()/(float)getGrandChildCount() : 0; - return p*100; - } - public float getGrandChildPercentageFail() { - float p = getGrandChildCount() > 0 ? ((float)getGrandChildCountFail()+(float)getGrandChildCountFatal())/(float)getGrandChildCount() : 0; - return p*100; - } - public float getGrandChildPercentageOthers() { - float p = getGrandChildCount() > 0 ? (((float)getGrandChildCountWarning()+(float)getGrandChildCountError()+(float)getGrandChildCountSkip()+(float)getGrandChildCountInfo())/(float)getGrandChildCount()) : 0; - return p*100; - } - public float getGrandChildPercentageSkip() { - float p = getGrandChildCount() > 0 ? (float)getGrandChildCountSkip()/(float)getGrandChildCount() : 0; - return p*100; - } - - private void refreshStats() { - testList.forEach(this::addTestForStatusStatsUpdate); - } - - private void addTestForStatusStatsUpdate(Test test) { - if (test.isBehaviorDrivenType() || (test.hasChildren() && test.getChildrenNodes().get(0).isBehaviorDrivenType())) { - updateGroupCountsBDD(test); - return; - } - - if (strategy == AnalysisStrategy.TEST || strategy == AnalysisStrategy.CLASS) { - updateGroupCountsTestStrategy(test); - return; - } - - if (strategy == AnalysisStrategy.SUITE) { - updateGroupCountsSuiteStrategy(test); - return; - } - - throw new InvalidAnalysisStrategyException("No such strategy found: " + strategy); - } - - private void updateGroupCountsSuiteStrategy(Test test) { - incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); - - if (test.hasChildren()) { - test.getChildrenNodes().getAll().forEach(x -> { - incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); - - if (x.hasChildren()) - x.getChildrenNodes().getAll().forEach(n -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus())); - }); - } - } - - private void updateGroupCountsBDD(Test test) { - incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); - - if (test.hasChildren()) { - test.getChildrenNodes().getAll().forEach(x -> { - if (x.getBehaviorDrivenType() == Scenario.class) - incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); - - if (x.hasChildren()) { - x.getChildrenNodes().getAll().forEach(n -> { - if (n.getBehaviorDrivenType() == Scenario.class) { - incrementItemCountByStatus(ItemLevel.CHILD, n.getStatus()); - - n.getChildrenNodes().getAll().forEach(z -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, z.getStatus())); - } - else { - incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus()); - } - }); - } - }); - } - } - - private void updateGroupCountsTestStrategy(Test test) { - incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); - - if (test.hasChildren()) { - updateGroupCountsTestStrategyChildren(test); - } - } - - private void updateGroupCountsTestStrategyChildren(Test test) { - test.getChildrenNodes().getAll().forEach(x -> { - if (!x.hasChildren()) { - incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); - } else { - updateGroupCountsTestStrategyChildren(x); - } - }); - } - - enum ItemLevel { - PARENT, - CHILD, - GRANDCHILD - } - - private void incrementItemCountByStatus(ItemLevel item, Status status) { - switch (item) { - case PARENT: - incrementParent(status); - break; - - case CHILD: - incrementChild(status); - break; - - case GRANDCHILD: - incrementGrandChild(status); - break; - - default: - break; - } - } - - private void incrementParent(Status status) { - switch (status) { - case PASS: - parentPass++; - return; - case FAIL: - parentFail++; - break; - case FATAL: - parentFatal++; - break; - case ERROR: - parentError++; - break; - case WARNING: - parentWarning++; - break; - case SKIP: - parentSkip++; - break; - default: - break; - } - - parentExceptions++; - } - - private void incrementChild(Status status) { - switch (status) { - case PASS: - childPass++; - break; - case FAIL: - childFail++; - break; - case FATAL: - childFatal++; - break; - case ERROR: - childError++; - break; - case WARNING: - childWarning++; - break; - case SKIP: - childSkip++; - break; - case INFO: - childInfo++; - break; - case DEBUG: - childDebug++; - break; - default: - break; - } - - if (status != Status.PASS && status != Status.INFO) - childExceptions++; - } - - private void incrementGrandChild(Status status) { - switch (status) { - case PASS: - grandChildPass++; - break; - case FAIL: - grandChildFail++; - break; - case FATAL: - grandChildFatal++; - break; - case ERROR: - grandChildError++; - break; - case WARNING: - grandChildWarning++; - break; - case SKIP: - grandChildSkip++; - break; - case INFO: - grandChildInfo++; - break; - case DEBUG: - grandChildDebug++; - break; - default: - break; - } - - if (status != Status.PASS && status != Status.INFO) - grandChildExceptions++; - } -} + + private List testList; + private AnalysisStrategy strategy = AnalysisStrategy.TEST; + + private int parentPass = 0; + private int parentFail = 0; + private int parentFatal = 0; + private int parentError = 0; + private int parentWarning = 0; + private int parentSkip = 0; + private int parentExceptions = 0; + + private int childPass = 0; + private int childFail = 0; + private int childFatal = 0; + private int childError = 0; + private int childWarning = 0; + private int childSkip = 0; + private int childInfo = 0; + private int childDebug = 0; + private int childExceptions = 0; + + private int grandChildPass = 0; + private int grandChildFail = 0; + private int grandChildFatal = 0; + private int grandChildError = 0; + private int grandChildWarning = 0; + private int grandChildSkip = 0; + private int grandChildInfo = 0; + private int grandChildDebug = 0; + private int grandChildExceptions = 0; + + public ReportStatusStats(AnalysisStrategy strategy) { + this.strategy = strategy; + } + + public void refresh(List testList) { + reset(); + this.testList = testList; + refreshStats(); + } + + private void reset() { + parentPass = 0; + parentFail = 0; + parentFatal = 0; + parentError = 0; + parentWarning = 0; + parentSkip = 0; + parentExceptions = 0; + + childPass = 0; + childFail = 0; + childFatal = 0; + childError = 0; + childWarning = 0; + childSkip = 0; + childInfo = 0; + childExceptions = 0; + + grandChildPass = 0; + grandChildFail = 0; + grandChildFatal = 0; + grandChildError = 0; + grandChildWarning = 0; + grandChildSkip = 0; + grandChildInfo = 0; + grandChildExceptions = 0; + } + + public int getParentCount() { + return getParentCountPass() + getParentCountFail() + getParentCountFatal() + getParentCountError() + + getParentCountWarning() + getParentCountSkip(); + } + + public int getParentCountPass() { + return parentPass; + } + + public int getParentCountFail() { + return parentFail; + } + + public int getParentCountFatal() { + return parentFatal; + } + + public int getParentCountError() { + return parentError; + } + + public int getParentCountWarning() { + return parentWarning; + } + + public int getParentCountSkip() { + return parentSkip; + } + + public int getParentCountExceptions() { + return parentExceptions; + } + + public float getParentPercentagePass() { + float p = getParentCount() > 0 ? (float) getParentCountPass() / (float) getParentCount() : 0; + return p * 100; + } + + public float getParentPercentageFail() { + float p = getParentCount() > 0 + ? ((float) getParentCountFail() + (float) getParentCountFatal()) / (float) getParentCount() + : 0; + return p * 100; + } + + public float getParentPercentageOthers() { + float p = getParentCount() > 0 + ? ((float) getParentCountWarning() + (float) getParentCountError()) / (float) getParentCount() + : 0; + return p * 100; + } + + public float getParentPercentageSkip() { + float p = getParentCount() > 0 ? (float) getParentCountSkip() / (float) getParentCount() : 0; + return p * 100; + } + + public int getChildCount() { + return getChildCountPass() + getChildCountFail() + getChildCountFatal() + getChildCountError() + + getChildCountWarning() + getChildCountSkip() + getChildCountInfo(); + } + + public int getChildCountPass() { + return childPass; + } + + public int getChildCountFail() { + return childFail; + } + + public int getChildCountFatal() { + return childFatal; + } + + public int getChildCountError() { + return childError; + } + + public int getChildCountWarning() { + return childWarning; + } + + public int getChildCountSkip() { + return childSkip; + } + + public int getChildCountInfo() { + return childInfo; + } + + public int getChildCountDebug() { + return childDebug; + } + + public int getChildCountExceptions() { + return childExceptions; + } + + public float getChildPercentagePass() { + float p = getChildCount() > 0 ? (float) getChildCountPass() / (float) getChildCount() : 0; + return p * 100; + } + + public float getChildPercentageFail() { + float p = getChildCount() > 0 + ? ((float) getChildCountFail() + (float) getChildCountFatal()) / (float) getChildCount() + : 0; + return p * 100; + } + + public float getChildPercentageOthers() { + float p = getChildCount() > 0 + ? (((float) getChildCountWarning() + (float) getChildCountError() + (float) getChildCountSkip() + + (float) getChildCountInfo()) / (float) getChildCount()) + : 0; + return p * 100; + } + + public float getChildPercentageSkip() { + float p = getChildCount() > 0 ? (float) getChildCountSkip() / (float) getChildCount() : 0; + return p * 100; + } + + public int getGrandChildCount() { + return getGrandChildCountPass() + getGrandChildCountFail() + getGrandChildCountFatal() + + getGrandChildCountError() + getGrandChildCountWarning() + getGrandChildCountSkip() + + getGrandChildCountInfo(); + } + + public int getGrandChildCountPass() { + return grandChildPass; + } + + public int getGrandChildCountFail() { + return grandChildFail; + } + + public int getGrandChildCountFatal() { + return grandChildFatal; + } + + public int getGrandChildCountError() { + return grandChildError; + } + + public int getGrandChildCountWarning() { + return grandChildWarning; + } + + public int getGrandChildCountSkip() { + return grandChildSkip; + } + + public int getGrandChildCountInfo() { + return grandChildInfo; + } + + public int getGrandChildCountDebug() { + return grandChildDebug; + } + + public int getGrandChildCountExceptions() { + return grandChildExceptions; + } + + public float getGrandChildPercentagePass() { + float p = getGrandChildCount() > 0 ? (float) getGrandChildCountPass() / (float) getGrandChildCount() : 0; + return p * 100; + } + + public float getGrandChildPercentageFail() { + float p = getGrandChildCount() > 0 + ? ((float) getGrandChildCountFail() + (float) getGrandChildCountFatal()) / (float) getGrandChildCount() + : 0; + return p * 100; + } + + public float getGrandChildPercentageOthers() { + float p = getGrandChildCount() > 0 + ? (((float) getGrandChildCountWarning() + (float) getGrandChildCountError() + + (float) getGrandChildCountSkip() + (float) getGrandChildCountInfo()) + / (float) getGrandChildCount()) + : 0; + return p * 100; + } + + public float getGrandChildPercentageSkip() { + float p = getGrandChildCount() > 0 ? (float) getGrandChildCountSkip() / (float) getGrandChildCount() : 0; + return p * 100; + } + + private void refreshStats() { + testList.forEach(this::addTestForStatusStatsUpdate); + } + + private void addTestForStatusStatsUpdate(Test test) { + if (test.getBddType() != null || (!test.getNodeContext().isEmpty() && test.getNodeContext().get(0).getBddType() != null)) { + updateGroupCountsBDD(test); + return; + } + + if (strategy == AnalysisStrategy.TEST || strategy == AnalysisStrategy.CLASS) { + updateGroupCountsTestStrategy(test); + return; + } + + if (strategy == AnalysisStrategy.SUITE) { + updateGroupCountsSuiteStrategy(test); + return; + } + + throw new InvalidAnalysisStrategyException("No such strategy found: " + strategy); + } + + private void updateGroupCountsSuiteStrategy(Test test) { + incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); + + if (!test.getNodeContext().isEmpty()) { + for (Test x : test.getNodeContext().getAll()) { + incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); + if (!x.getNodeContext().isEmpty()) { + x.getNodeContext().getAll().forEach(n -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus())); + } + } + } + } + + private void updateGroupCountsBDD(Test test) { + incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); + + if (!test.getNodeContext().isEmpty()) { + for (Test x : test.getNodeContext().getAll()) { + if (x.getBddType() == Scenario.class) { + incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); + } + if (!x.getNodeContext().isEmpty()) { + for (Test n : x.getNodeContext().getAll()) { + if (n.getBddType() == Scenario.class) { + incrementItemCountByStatus(ItemLevel.CHILD, n.getStatus()); + n.getNodeContext().getAll() + .forEach(z -> incrementItemCountByStatus(ItemLevel.GRANDCHILD, z.getStatus())); + } else { + incrementItemCountByStatus(ItemLevel.GRANDCHILD, n.getStatus()); + } + } + } + } + } + } + + private void updateGroupCountsTestStrategy(Test test) { + incrementItemCountByStatus(ItemLevel.PARENT, test.getStatus()); + + if (!test.getNodeContext().isEmpty()) { + updateGroupCountsTestStrategyChildren(test); + } + } + + private void updateGroupCountsTestStrategyChildren(Test test) { + test.getNodeContext().getAll().forEach(x -> { + if (x.getNodeContext().isEmpty()) { + incrementItemCountByStatus(ItemLevel.CHILD, x.getStatus()); + } else { + updateGroupCountsTestStrategyChildren(x); + } + }); + } + + enum ItemLevel { + PARENT, CHILD, GRANDCHILD + } + + private void incrementItemCountByStatus(ItemLevel item, Status status) { + switch (item) { + case PARENT: + incrementParent(status); + break; + + case CHILD: + incrementChild(status); + break; + + case GRANDCHILD: + incrementGrandChild(status); + break; + + default: + break; + } + } + + private void incrementParent(Status status) { + switch (status) { + case PASS: + parentPass++; + return; + case FAIL: + parentFail++; + break; + case FATAL: + parentFatal++; + break; + case ERROR: + parentError++; + break; + case WARNING: + parentWarning++; + break; + case SKIP: + parentSkip++; + break; + default: + break; + } + + parentExceptions++; + } + + private void incrementChild(Status status) { + switch (status) { + case PASS: + childPass++; + break; + case FAIL: + childFail++; + break; + case FATAL: + childFatal++; + break; + case ERROR: + childError++; + break; + case WARNING: + childWarning++; + break; + case SKIP: + childSkip++; + break; + case INFO: + childInfo++; + break; + case DEBUG: + childDebug++; + break; + default: + break; + } + + if (status != Status.PASS && status != Status.INFO) + childExceptions++; + } + + private void incrementGrandChild(Status status) { + switch (status) { + case PASS: + grandChildPass++; + break; + case FAIL: + grandChildFail++; + break; + case FATAL: + grandChildFatal++; + break; + case ERROR: + grandChildError++; + break; + case WARNING: + grandChildWarning++; + break; + case SKIP: + grandChildSkip++; + break; + case INFO: + grandChildInfo++; + break; + case DEBUG: + grandChildDebug++; + break; + default: + break; + } + + if (status != Status.PASS && status != Status.INFO) + grandChildExceptions++; + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/RunResult.java b/src/main/java/com/aventstack/extentreports/RunResult.java index b608cf9..426197f 100644 --- a/src/main/java/com/aventstack/extentreports/RunResult.java +++ b/src/main/java/com/aventstack/extentreports/RunResult.java @@ -1,5 +1,4 @@ package com.aventstack.extentreports; - /** * Marker interface for the run result with a single getStatus() method * @@ -8,4 +7,4 @@ public interface RunResult { Status getStatus(); -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/SourceProvider.java b/src/main/java/com/aventstack/extentreports/SourceProvider.java deleted file mode 100644 index eccc815..0000000 --- a/src/main/java/com/aventstack/extentreports/SourceProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.aventstack.extentreports; - -/** - * Some formatters can provide the source which is also written to file, - * for example, Email formatters or reporters. Along with writing the contents - * to a file, you can retrieve the source using which an email can be sent. - */ -public interface SourceProvider { - - String getSource(); - -} diff --git a/src/main/java/com/aventstack/extentreports/Status.java b/src/main/java/com/aventstack/extentreports/Status.java index 94a17aa..f4ca613 100644 --- a/src/main/java/com/aventstack/extentreports/Status.java +++ b/src/main/java/com/aventstack/extentreports/Status.java @@ -1,5 +1,4 @@ package com.aventstack.extentreports; - import java.io.Serializable; import java.util.Arrays; import java.util.Collection; diff --git a/src/main/java/com/aventstack/extentreports/StatusConfigurator.java b/src/main/java/com/aventstack/extentreports/StatusConfigurator.java index 70713b3..9e5cc6a 100644 --- a/src/main/java/com/aventstack/extentreports/StatusConfigurator.java +++ b/src/main/java/com/aventstack/extentreports/StatusConfigurator.java @@ -4,26 +4,29 @@ public class StatusConfigurator { - private static class StatusConfiguratorInstance { - static final StatusConfigurator INSTANCE = new StatusConfigurator(); - - private StatusConfiguratorInstance() { } - } - - private StatusConfigurator() { } - - public static StatusConfigurator getInstance() { - return StatusConfiguratorInstance.INSTANCE; - } - - public List getStatusHierarchy() { - return Status.getStatusHierarchy(); - } - public void setStatusHierarchy(List statusHierarchy) { - Status.setStatusHierarchy(statusHierarchy); - } - - public void resetStatusHierarchy() { - Status.resetStatusHierarchy(); - } + private static class StatusConfiguratorInstance { + static final StatusConfigurator INSTANCE = new StatusConfigurator(); + + private StatusConfiguratorInstance() { + } + } + + private StatusConfigurator() { + } + + public static StatusConfigurator getInstance() { + return StatusConfiguratorInstance.INSTANCE; + } + + public List getStatusHierarchy() { + return Status.getStatusHierarchy(); + } + + public void setStatusHierarchy(List statusHierarchy) { + Status.setStatusHierarchy(statusHierarchy); + } + + public void resetStatusHierarchy() { + Status.resetStatusHierarchy(); + } } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/SystemAttributeContext.java b/src/main/java/com/aventstack/extentreports/SystemAttributeContext.java deleted file mode 100644 index 1bf48ea..0000000 --- a/src/main/java/com/aventstack/extentreports/SystemAttributeContext.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.aventstack.extentreports; - -import java.util.ArrayList; -import java.util.List; - -import com.aventstack.extentreports.model.SystemAttribute; - -/** - * A simple key-value pair collection to store System/Environment information - * - */ -public class SystemAttributeContext { - - private List sysAttrCollection; - - public SystemAttributeContext() { - sysAttrCollection = new ArrayList<>(); - } - - public void setSystemAttribute(SystemAttribute sa) { - sysAttrCollection.add(sa); - } - - public List getSystemAttributeList() { return sysAttrCollection; } - - public void clear() { - sysAttrCollection.clear(); - } -} diff --git a/src/main/java/com/aventstack/extentreports/TestAttributeTestContextProvider.java b/src/main/java/com/aventstack/extentreports/TestAttributeTestContextProvider.java deleted file mode 100644 index d24b48a..0000000 --- a/src/main/java/com/aventstack/extentreports/TestAttributeTestContextProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aventstack.extentreports; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; - -import com.aventstack.extentreports.model.Test; -import com.aventstack.extentreports.model.TestAttribute; -import com.aventstack.extentreports.model.TestAttributeTestContext; - -/** - * Uses an attribute context for {@link TestAttribute} (Category, Device, Author etc.) - * and tracks the collection of tests segregated by the type {@link TestAttribute} - * - * @param A {@link TestAttribute} type - */ -public class TestAttributeTestContextProvider { - - private List> testAttrCollection; - - public TestAttributeTestContextProvider() { - testAttrCollection = new ArrayList<>(); - } - - public void setAttributeContext(T attr, Test test) { - Optional> testOptionalTestContext = testAttrCollection - .stream() - .filter(x -> x.getName().equals(attr.getName())) - .findFirst(); - - if (testOptionalTestContext.isPresent()) { - List testList = testOptionalTestContext.get().getTestList(); - - boolean b = testList - .stream() - .anyMatch(t -> t.getID() == test.getID()); - - if (!b) { - testOptionalTestContext.get().setTest(test); - } - testOptionalTestContext.get().refreshTestStatusCounts(); - } - else { - TestAttributeTestContext testAttrContext = new TestAttributeTestContext<>(attr); - testAttrContext.setTest(test); - testAttrCollection.add(testAttrContext); - } - } - - public void removeTest(Test test) { - Iterator> iter = testAttrCollection.iterator(); - while (iter.hasNext()) { - TestAttributeTestContext context = iter.next(); - TestRemover.remove(context.getTestList(), test); - if (context.isEmpty()) { - iter.remove(); - } - } - } - - public List> getTestAttributeTestContextList() { - return testAttrCollection; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/TestListener.java b/src/main/java/com/aventstack/extentreports/TestListener.java index e526426..5201df4 100644 --- a/src/main/java/com/aventstack/extentreports/TestListener.java +++ b/src/main/java/com/aventstack/extentreports/TestListener.java @@ -7,98 +7,90 @@ import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.Log; import com.aventstack.extentreports.model.ScreenCapture; -import com.aventstack.extentreports.model.Screencast; import com.aventstack.extentreports.model.Test; /** * Listener methods invoked when an event occurs in the report: * *

      - *
    • A test or node is started
    • - *
    • A category or author is added
    • - *
    • A media object is added etc.
    • + *
    • A test or node is started
    • + *
    • A category or author is added
    • + *
    • A media object is added etc.
    • *
    */ public interface TestListener { - - /** - * Invoked when a test is started using createTest() - * - * @param test {@link com.aventstack.extentreports.model.Test} object - */ - void onTestStarted(Test test); - - /** - * Invoked when a test is removed using removeTest() - * - * @param test {@link com.aventstack.extentreports.model.Test} object - */ - void onTestRemoved(Test test); - - /** - * Invoked when a node is started using createNode() - * - * @param node {@link com.aventstack.extentreports.model.Test} object - */ - void onNodeStarted(Test node); - - /** - * Invoked each time a log is added to any test/node - * - * @param test {@link com.aventstack.extentreports.model.Test} object - * @param log {@link com.aventstack.extentreports.model.Log} object - */ - void onLogAdded(Test test, Log log); - - /** - * Invoked each time a category is assigned to any test/node - * - * @param test {@link com.aventstack.extentreports.model.Test} object - * @param category {@link com.aventstack.extentreports.model.Category} object - */ - void onCategoryAssigned(Test test, Category category); - - /** - * Invoked each time an author is assigned to any test/node - * - * @param test {@link com.aventstack.extentreports.model.Test} object - * @param author {@link com.aventstack.extentreports.model.Author} object - */ - void onAuthorAssigned(Test test, Author author); - - /** - * Invoked each time a device is assigned to any test/node - * - * @param test {@link com.aventstack.extentreports.model.Test} object - * @param device {@link com.aventstack.extentreports.model.Device} object - */ - void onDeviceAssigned(Test test, Device device); - - /** - * Invoked each time a screencapture is added to test - * - * @param test {@link com.aventstack.extentreports.model.Test} object - * @param screenCapture {@link com.aventstack.extentreports.model.ScreenCapture} object - * @throws IOException Exception thrown if the media object is not found - */ - void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException; - - /** - * Invoked each time a screencapture is added to log - * - * @param log {@link com.aventstack.extentreports.model.Log} object - * @param screenCapture {@link com.aventstack.extentreports.model.ScreenCapture} object - * @throws IOException Exception thrown if the media object is not found - */ - void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException; - - /** - * Invoked each time a screencast is added - * - * @param test {@link com.aventstack.extentreports.model.Test} object - * @param screencast {@link com.aventstack.extentreports.model.Screencast} object - * @throws IOException Exception thrown if the media object is not found - */ - void onScreencastAdded(Test test, Screencast screencast) throws IOException; - -} + + /** + * Invoked when a test is started using createTest() + * + * @param test {@link com.aventstack.extentreports.model.Test} object + */ + void onTestStarted(Test test); + + /** + * Invoked when a test is removed using removeTest() + * + * @param test {@link com.aventstack.extentreports.model.Test} object + */ + void onTestRemoved(Test test); + + /** + * Invoked when a node is started using createNode() + * + * @param node {@link com.aventstack.extentreports.model.Test} object + */ + void onNodeStarted(Test node); + + /** + * Invoked each time a log is added to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param log {@link com.aventstack.extentreports.model.Log} object + */ + void onLogAdded(Test test, Log log); + + /** + * Invoked each time a category is assigned to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param category {@link com.aventstack.extentreports.model.Category} object + */ + void onCategoryAssigned(Test test, Category category); + + /** + * Invoked each time an author is assigned to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param author {@link com.aventstack.extentreports.model.Author} object + */ + void onAuthorAssigned(Test test, Author author); + + /** + * Invoked each time a device is assigned to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param device {@link com.aventstack.extentreports.model.Device} object + */ + void onDeviceAssigned(Test test, Device device); + + /** + * Invoked each time a screencapture is added to test + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param screenCapture {@link com.aventstack.extentreports.model.ScreenCapture} + * object + * @throws IOException Exception thrown if the media object is not found + */ + void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException; + + /** + * Invoked each time a screencapture is added to log + * + * @param log {@link com.aventstack.extentreports.model.Log} object + * @param screenCapture {@link com.aventstack.extentreports.model.ScreenCapture} + * object + * @throws IOException Exception thrown if the media object is not found + */ + void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException; + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/TestRemover.java b/src/main/java/com/aventstack/extentreports/TestRemover.java deleted file mode 100644 index 09a310e..0000000 --- a/src/main/java/com/aventstack/extentreports/TestRemover.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.aventstack.extentreports; - -import java.util.List; -import java.util.stream.Collectors; - -import com.aventstack.extentreports.model.Test; - -class TestRemover { - - /** - * Helper for removing test recursively. This flag determines when to break - * out of recursion - */ - private static boolean removed = false; - - private TestRemover() { } - - /** - * Remove a test using its unique ID from a list - * - * @param list a list of {@link Test} - * @param test {@link Test} to be removed - */ - public static void remove(List testList, Test test) { - removed = false; - findAndRemoveTest(testList, test); - testList.forEach(Test::end); - } - - /** - * Recursively traverses all tests, nodes upto the last leaf to find and remove - * the specified test - * - * @param list a list of {@link Test} - * @param test {@link Test} to be removed - */ - private static void findAndRemoveTest(List list, Test test) { - List filteredTestList = list - .stream() - .filter(x -> x.getID() == test.getID()) - .collect(Collectors.toList()); - - if (filteredTestList.size() == 1) { - removeTest(list, filteredTestList.get(0)); - removed = true; - return; - } - - for (Test t : list) { - if (removed) { - return; - } - findAndRemoveTest(t.getChildrenNodes().getAll(), test); - } - } - - /** - * Removes the test from a given list of tests - * - * @param list a list of {@link Test} - * @param test {@link Test} to be removed - */ - private static void removeTest(List list, Test test) { - list.remove(test); - } - -} diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java b/src/main/java/com/aventstack/extentreports/configuration/ConfigurationBuilder.java similarity index 65% rename from src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java rename to src/main/java/com/aventstack/extentreports/configuration/ConfigurationBuilder.java index 4e47f9a..c66ec17 100644 --- a/src/main/java/com/aventstack/extentreports/externalconfig/ConfigLoader.java +++ b/src/main/java/com/aventstack/extentreports/configuration/ConfigurationBuilder.java @@ -1,4 +1,4 @@ -package com.aventstack.extentreports.externalconfig; +package com.aventstack.extentreports.configuration; import java.io.File; import java.io.FileInputStream; @@ -20,22 +20,14 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import com.aventstack.extentreports.externalconfig.model.ConfigMap; +public class ConfigurationBuilder { -public class ConfigLoader { + private static final Logger logger = Logger.getLogger(ConfigurationBuilder.class.getName()); - private static final Logger logger = Logger.getLogger(ConfigLoader.class.getName()); - - private ConfigMap configContext; + private ConfigurationStore store = new ConfigurationStore(); private InputStream stream; - ConfigLoader() { - configContext = new ConfigMap(); - } - - public ConfigLoader(URL url) { - this(); - + public ConfigurationBuilder(URL url) { try { stream = url.openStream(); } catch (IOException e) { @@ -43,9 +35,7 @@ public ConfigLoader(URL url) { } } - public ConfigLoader(File file, Boolean silent) { - this(); - + public ConfigurationBuilder(File file, Boolean silent) { try { if (silent && !file.exists()) return; @@ -55,18 +45,18 @@ public ConfigLoader(File file, Boolean silent) { } } - public ConfigMap getConfigurationHash() { + public ConfigurationStore getConfigurationStore() { if (stream == null) return null; - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder; + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder; String value; try { - dBuilder = dbFactory.newDocumentBuilder(); + documentBuilder = documentBuilderFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(stream); + Document doc = documentBuilder.parse(stream); doc.getDocumentElement().normalize(); NodeList nodeList = doc.getElementsByTagName("configuration").item(0).getChildNodes(); @@ -80,15 +70,15 @@ public ConfigMap getConfigurationHash() { value = el.getTextContent(); value = el instanceof CharacterData ? ((CharacterData) el).getData() : value; - configContext.setConfig(el.getNodeName(), value); + store.storeConfig(el.getNodeName(), value); } } - return configContext; + return store; } catch (IOException | SAXException | ParserConfigurationException e) { - logger.log(Level.SEVERE, "Config", e); + logger.log(Level.SEVERE, "Failed to load external configuration", e); } return null; } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/configuration/ConfigurationStore.java b/src/main/java/com/aventstack/extentreports/configuration/ConfigurationStore.java new file mode 100644 index 0000000..51e2acb --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/configuration/ConfigurationStore.java @@ -0,0 +1,43 @@ +package com.aventstack.extentreports.configuration; + +import java.util.HashMap; +import java.util.Map; + +public class ConfigurationStore { + + private Map store = new HashMap(); + + public Map getStore() { + return store; + } + + public void storeConfig(String key, Object value) { + store.put(key, value); + } + + public boolean containsConfig(String k) { + return store.containsKey(k); + } + + public void removeConfig(String k) { + store.remove(k); + } + + public Object getConfig(String k) { + return store.containsKey(k) ? store.get(k) : null; + } + + public void extendConfig(Map map) { + map.forEach((key, value) -> this.storeConfig(key, value)); + } + + public void extendConfig(ConfigurationStore config) { + Map map = config.store; + this.extendConfig(map); + } + + public boolean isEmpty() { + return store.isEmpty(); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/convert/JsonDeserializer.java b/src/main/java/com/aventstack/extentreports/convert/JsonDeserializer.java new file mode 100644 index 0000000..669f6d0 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/convert/JsonDeserializer.java @@ -0,0 +1,24 @@ +package com.aventstack.extentreports.convert; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +import com.aventstack.extentreports.model.Test; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +class JsonDeserializer { + + public static List deserialize(File f) throws IOException { + Gson gson = new Gson(); + String json = new String(Files.readAllBytes(f.toPath())); + Type t = new TypeToken>() {}.getType(); + List tests = gson.fromJson(json, t); + return tests; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java b/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java new file mode 100644 index 0000000..2b838c5 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java @@ -0,0 +1,38 @@ +package com.aventstack.extentreports.convert; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import com.aventstack.extentreports.ExtentReports; +import com.aventstack.extentreports.ExtentTest; +import com.aventstack.extentreports.model.Test; + +public class TestModelReportBuilder { + + public void recreateModelFromJson(ExtentReports extent, File jsonFile) throws IOException { + extent.setReportUsesManualConfiguration(true); + List tests = JsonDeserializer.deserialize(jsonFile); + for (Test test : tests) { + recreateTest(test, extent.createTest(test.getName() + "json", test.getDescription())); + } + extent.setReportUsesManualConfiguration(false); + } + + public void recreateTest(Test test, ExtentTest extentTest) { + // create events + test.getLogContext().getAll().forEach(x -> extentTest.log(x.getStatus(), x.getDetails())); + + // assign attributes + test.getAuthorContext().getAll().forEach(x -> extentTest.assignAuthor(x.getName())); + test.getCategoryContext().getAll().forEach(x -> extentTest.assignCategory(x.getName())); + test.getDeviceContext().getAll().forEach(x -> extentTest.assignDevice(x.getName())); + + // handle nodes + for (Test node : test.getNodeContext().getAll()) { + ExtentTest extentNode = extentTest.createNode(node.getName()); + recreateTest(node, extentNode); + } + } + +} diff --git a/src/main/java/com/aventstack/extentreports/exceptions/ExtentTestInterruptedException.java b/src/main/java/com/aventstack/extentreports/exceptions/ExtentTestInterruptedException.java deleted file mode 100644 index fda727b..0000000 --- a/src/main/java/com/aventstack/extentreports/exceptions/ExtentTestInterruptedException.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.aventstack.extentreports.exceptions; - -@SuppressWarnings("serial") -public class ExtentTestInterruptedException extends RuntimeException { - public ExtentTestInterruptedException(Throwable t) { - super(t); - } - - public ExtentTestInterruptedException(String string) { - super(string); - } - - public ExtentTestInterruptedException(String string, Throwable t) { - super(string, t); - } - -} diff --git a/src/main/java/com/aventstack/extentreports/exceptions/InvalidFileException.java b/src/main/java/com/aventstack/extentreports/exceptions/InvalidFileException.java deleted file mode 100644 index 4cf981b..0000000 --- a/src/main/java/com/aventstack/extentreports/exceptions/InvalidFileException.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.aventstack.extentreports.exceptions; - -@SuppressWarnings("serial") -public class InvalidFileException extends Exception { - public InvalidFileException() { - super(); - } - - public InvalidFileException(Throwable t) { - super(t); - } - - public InvalidFileException(String string) { - super(string); - } - - public InvalidFileException(String string, Throwable t) { - super(string, t); - } - -} diff --git a/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java b/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java deleted file mode 100644 index 0f80409..0000000 --- a/src/main/java/com/aventstack/extentreports/externalconfig/model/ConfigMap.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.aventstack.extentreports.externalconfig.model; - -import java.util.HashMap; -import java.util.Map; - -public class ConfigMap { - - private Map configMap; - - public ConfigMap() { - configMap = new HashMap(); - } - - public void setConfig(String key, Object value) { - configMap.put(key, value); - } - - public boolean containsKey(String k) { - return configMap.containsKey(k); - } - - void removeKey(String k) { - configMap.remove(k); - } - - public Object getValue(String k) { - return configMap.containsKey(k) ? configMap.get(k) : null; - } - - public void appendConfig(Map configurations) { - // This might create a hard dependency on Java 8. As Lambda function were - // introduced in Java *. - // We can instead have an in-line implementation of BiConsumer interface - configurations.forEach((key, value) -> this.setConfig(key, value)); - } - - public void appendConfig(ConfigMap configurations) { - Map map = configurations.configMap; - this.appendConfig(map); - } - - public boolean isEmpty() { - return configMap.isEmpty(); - } -} diff --git a/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialect.java b/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialect.java index 974510e..37b51a5 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialect.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialect.java @@ -5,7 +5,7 @@ /** *

    - * Modified version of GherkinKeyword.java from cucumber/gherkin. Source url: + * Modified version of GherkinKeyword.java from cucumber/gherkin. Source url: * https://raw.githubusercontent.com/cucumber/cucumber/master/gherkin/java/src/main/java/gherkin/GherkinDialect.java * *

    @@ -13,21 +13,23 @@ * */ public class GherkinDialect { - private final Map> keywords; - private String language; + + private final Map> keywords; + private String language; - public GherkinDialect(String language, Map> keywords) { - this.language = language; - this.keywords = keywords; - } + public GherkinDialect(String language, Map> keywords) { + keywords.remove("name"); + keywords.remove("native"); + this.language = language; + this.keywords = keywords; + } - public Map> getKeywords() { - keywords.remove("name"); - keywords.remove("native"); - return keywords; - } + public Map> getKeywords() { + return keywords; + } - public String getLanguage() { - return language; - } + public String getLanguage() { + return language; + } + } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialectProvider.java b/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialectProvider.java index 32c815b..34441a7 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialectProvider.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/GherkinDialectProvider.java @@ -10,7 +10,8 @@ /** *

    - * Modified version of GherkinDialectProvider.java from cucumber/gherkin. Source url: + * Modified version of GherkinDialectProvider.java from cucumber/gherkin. Source + * url: * https://github.com/cucumber/cucumber/blob/master/gherkin/java/src/main/java/gherkin/GherkinDialectProvider.java. * *

    @@ -20,54 +21,57 @@ @SuppressWarnings("unchecked") public class GherkinDialectProvider { - private static final String DEFAULT_LANGUAGE = "en"; - private static final String GHERKIN_LANGUAGES_JSON_URL = "https://github.com/cucumber/cucumber/blob/master/gherkin/java/src/main/resources/gherkin/gherkin-languages.json"; - - private static GherkinDialect currentDialect; - private static Map>> dialects; - private static String language; - - static { - Gson gson = new Gson(); - try { - Reader d = new InputStreamReader(GherkinDialectProvider.class.getResourceAsStream("gherkin-languages.json"), "UTF-8"); - dialects = gson.fromJson(d, Map.class); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - public static GherkinDialect getDialect() { - return currentDialect; - } - - public static String getDefaultLanguage() { - return DEFAULT_LANGUAGE; - } - - public static String getLanguage() { - if (language == null || language.isEmpty()) - language = DEFAULT_LANGUAGE; - - return language; - } - - /** - * Sets/changes the default language - * - * @param lang A valid dialect from - * gherkin-languages.json - * - * @throws UnsupportedEncodingException Thrown if the language is one of the supported language from - * gherkin-languages.json - */ - public static void setLanguage(String lang) throws UnsupportedEncodingException { - language = lang; - Map> map = dialects.get(GherkinDialectProvider.language); - if (map == null) - throw new UnsupportedEncodingException("Invalid language [" + language + "]. See list of supported languages: " + GHERKIN_LANGUAGES_JSON_URL); - - currentDialect = new GherkinDialect(language, map); - } - + private static final String DEFAULT_LANGUAGE = "en"; + private static final String GHERKIN_LANGUAGES_JSON_URL = "https://github.com/cucumber/cucumber/blob/master/gherkin/gherkin-languages.json"; + private static final String GHERKIN_LANGUAGES_PATH = "gherkin-languages.json"; + + private static GherkinDialect currentDialect; + private static Map>> dialects; + private static String language; + + static { + Gson gson = new Gson(); + try { + Reader d = new InputStreamReader(GherkinDialectProvider.class.getResourceAsStream(GHERKIN_LANGUAGES_PATH), + "UTF-8"); + dialects = gson.fromJson(d, Map.class); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public static GherkinDialect getDialect() { + return currentDialect; + } + + public static String getDefaultLanguage() { + return DEFAULT_LANGUAGE; + } + + public static String getLanguage() { + if (language == null || language.isEmpty()) { + language = DEFAULT_LANGUAGE; + } + return language; + } + + /** + * Sets/changes the default language + * + * @param lang A valid dialect from + * + * @throws UnsupportedEncodingException Thrown if the language is one of the + * supported language from + */ + public static void setLanguage(String lang) throws UnsupportedEncodingException { + language = lang; + Map> map = dialects.get(GherkinDialectProvider.language); + if (map == null) { + throw new UnsupportedEncodingException("Invalid language [" + language + "]. See list of supported languages: " + GHERKIN_LANGUAGES_JSON_URL); + } + currentDialect = new GherkinDialect(language, map); + } + } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/And.java b/src/main/java/com/aventstack/extentreports/gherkin/model/And.java index fdf6983..c2a2bff 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/And.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/And.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class And - implements IGherkinFormatterModel, Serializable { +public class And implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 8543289653944756660L; private static final String VALUE = "And"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/Asterisk.java b/src/main/java/com/aventstack/extentreports/gherkin/model/Asterisk.java index 05fe3af..c6e10d7 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/Asterisk.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/Asterisk.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class Asterisk - implements IGherkinFormatterModel, Serializable { +public class Asterisk implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 7251419811428200133L; private static final String VALUE = "*"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/Background.java b/src/main/java/com/aventstack/extentreports/gherkin/model/Background.java index e646aaa..1e42713 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/Background.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/Background.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class Background - implements IGherkinFormatterModel, Serializable { +public class Background implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = -955371501488725151L; private static final String VALUE = "Background"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/But.java b/src/main/java/com/aventstack/extentreports/gherkin/model/But.java index c7f66b6..6d88158 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/But.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/But.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class But - implements IGherkinFormatterModel, Serializable { +public class But implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 3420514631996827220L; private static final String VALUE = "But"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/Feature.java b/src/main/java/com/aventstack/extentreports/gherkin/model/Feature.java index 4d55c8b..6475396 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/Feature.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/Feature.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class Feature - implements IGherkinFormatterModel, Serializable { +public class Feature implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = -4719215211721789414L; private static final String VALUE = "Feature"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/GherkinModelSerializer.java b/src/main/java/com/aventstack/extentreports/gherkin/model/GherkinModelSerializer.java new file mode 100644 index 0000000..242fefa --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/GherkinModelSerializer.java @@ -0,0 +1,23 @@ +package com.aventstack.extentreports.gherkin.model; + +import java.io.IOException; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +public class GherkinModelSerializer extends TypeAdapter { + + @Override + public void write(JsonWriter out, IGherkinFormatterModel value) throws IOException { + // TODO Auto-generated method stub + + } + + @Override + public IGherkinFormatterModel read(JsonReader in) throws IOException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/Given.java b/src/main/java/com/aventstack/extentreports/gherkin/model/Given.java index 5ac6eca..483b0d2 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/Given.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/Given.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class Given - implements IGherkinFormatterModel, Serializable { +public class Given implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 939197985263690070L; private static final String VALUE = "Given"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/IGherkinFormatterModel.java b/src/main/java/com/aventstack/extentreports/gherkin/model/IGherkinFormatterModel.java index d9b3a0e..d150968 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/IGherkinFormatterModel.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/IGherkinFormatterModel.java @@ -2,5 +2,5 @@ import java.io.Serializable; -public interface IGherkinFormatterModel - extends Serializable { } +public interface IGherkinFormatterModel extends Serializable { +} diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/Scenario.java b/src/main/java/com/aventstack/extentreports/gherkin/model/Scenario.java index 8f85f55..683f4d1 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/Scenario.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/Scenario.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class Scenario - implements IGherkinFormatterModel, Serializable { +public class Scenario implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 7401124129196617280L; private static final String VALUE = "Scenario"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/ScenarioOutline.java b/src/main/java/com/aventstack/extentreports/gherkin/model/ScenarioOutline.java index 481c890..6b84733 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/ScenarioOutline.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/ScenarioOutline.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class ScenarioOutline - implements IGherkinFormatterModel, Serializable { +public class ScenarioOutline implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = -2058398543903906031L; private static final String VALUE = "Scenario Outline"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/Then.java b/src/main/java/com/aventstack/extentreports/gherkin/model/Then.java index 427a738..2ad2bc7 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/Then.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/Then.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class Then - implements IGherkinFormatterModel, Serializable { +public class Then implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 2493591502473169772L; private static final String VALUE = "Then"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/gherkin/model/When.java b/src/main/java/com/aventstack/extentreports/gherkin/model/When.java index 5da0d15..d9460db 100644 --- a/src/main/java/com/aventstack/extentreports/gherkin/model/When.java +++ b/src/main/java/com/aventstack/extentreports/gherkin/model/When.java @@ -2,19 +2,18 @@ import java.io.Serializable; -public class When - implements IGherkinFormatterModel, Serializable { +public class When implements IGherkinFormatterModel, Serializable { private static final long serialVersionUID = 8337259741948416898L; private static final String VALUE = "When"; - + public static String getGherkinName() { return VALUE; } - + @Override public String toString() { return getGherkinName(); } - + } diff --git a/src/main/java/com/aventstack/extentreports/io/FileWriterBuffered.java b/src/main/java/com/aventstack/extentreports/io/FileWriterBuffered.java new file mode 100644 index 0000000..76b1bcb --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/io/FileWriterBuffered.java @@ -0,0 +1,35 @@ +package com.aventstack.extentreports.io; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class FileWriterBuffered { + + private static class WriterInstance { + static final FileWriterBuffered INSTANCE = new FileWriterBuffered(); + + private WriterInstance() { + } + } + + static final Logger logger = Logger.getLogger(FileWriterBuffered.class.getName()); + + private FileWriterBuffered() { + } + + public synchronized void write(final File f, String text) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(f))) { + writer.write(text); + } catch (Exception e) { + logger.log(Level.SEVERE, f.getPath(), e); + } + } + + public static FileWriterBuffered getInstance() { + return WriterInstance.INSTANCE; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/io/ResourceUtil.java b/src/main/java/com/aventstack/extentreports/io/ResourceUtil.java new file mode 100644 index 0000000..6069081 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/io/ResourceUtil.java @@ -0,0 +1,54 @@ +package com.aventstack.extentreports.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +public class ResourceUtil { + + public static void moveResource(String resourcePath, String copyPath) { + if (copyPath != null) + copyPath = copyPath.replace("\\", "/"); + if (resourcePath != null) + resourcePath = resourcePath.replace("\\", "/"); + + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + InputStream in = classLoader.getResourceAsStream(resourcePath); + + FileOutputStream out = new FileOutputStream(copyPath); + + byte[] b = new byte[1024]; + int noOfBytes = 0; + + while ((noOfBytes = in.read(b)) != -1) { + out.write(b, 0, noOfBytes); + } + + in.close(); + out.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void moveBinaryFile(String resourcePath, String copyPath) { + URI uri = new File(resourcePath).toURI(); + Path path = Paths.get(uri); + try { + Files.copy(path, new File(copyPath).toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/markuputils/CodeBlock.java b/src/main/java/com/aventstack/extentreports/markuputils/CodeBlock.java index ea8a18a..d378816 100644 --- a/src/main/java/com/aventstack/extentreports/markuputils/CodeBlock.java +++ b/src/main/java/com/aventstack/extentreports/markuputils/CodeBlock.java @@ -1,43 +1,65 @@ package com.aventstack.extentreports.markuputils; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; -class CodeBlock implements Markup { - - private static final long serialVersionUID = -5532095355983830164L; - - private static final AtomicInteger id = new AtomicInteger(0); - - private String code; - private CodeLanguage lang; - - public void setCodeBlock(String code) { - this.code = code; - } - public String getCodeBlock() { - return code; - } - - public void setCodeBlock(String code, CodeLanguage lang) { - this.code = code; - this.lang = lang; - } - - @Override - public String getMarkup() { - if (lang == CodeLanguage.JSON) { - int index = id.getAndIncrement(); - return "

    " + - ""; - } - - String lhs = ""; - - return lhs + code + rhs; - } +import freemarker.template.Template; +import freemarker.template.TemplateException; + +class CodeBlock extends MarkupTemplate implements Markup { + + private static final long serialVersionUID = -5532095355983830164L; + private static final AtomicInteger id = new AtomicInteger(0); + private static final String CODEBLOCK_TEMPLATE = "codeblock.ftl"; + private static final String CODEBLOCK_JSON_TEMPLATE = "codeblock.json.ftl"; + private static Template codeblock; + private static Template codeblockJson; + private String code; + private CodeLanguage lang; + + static { + try { + codeblock = ft.createTemplate(CODEBLOCK_TEMPLATE); + codeblockJson = ft.createTemplate(CODEBLOCK_JSON_TEMPLATE); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void setCodeBlock(String code) { + this.code = code; + } + + public String getCodeBlock() { + return code; + } + + public void setCodeBlock(String code, CodeLanguage lang) { + this.code = code; + this.lang = lang; + } + + @Override + public String getMarkup() { + int index = 0; + Template t = codeblock; + if (lang == CodeLanguage.JSON) { + index = id.getAndIncrement(); + t = codeblockJson; + } + Map map = new HashMap<>(); + map.put("code", code); + map.put("index", index); + try { + return ft.getSource(t, map); + } catch (TemplateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } } diff --git a/src/main/java/com/aventstack/extentreports/markuputils/Markup.java b/src/main/java/com/aventstack/extentreports/markuputils/Markup.java index ff0a803..bd8856c 100644 --- a/src/main/java/com/aventstack/extentreports/markuputils/Markup.java +++ b/src/main/java/com/aventstack/extentreports/markuputils/Markup.java @@ -4,5 +4,5 @@ @FunctionalInterface public interface Markup extends Serializable { - String getMarkup(); + String getMarkup(); } diff --git a/src/main/java/com/aventstack/extentreports/markuputils/MarkupHelper.java b/src/main/java/com/aventstack/extentreports/markuputils/MarkupHelper.java index 92a12a5..42ca33d 100644 --- a/src/main/java/com/aventstack/extentreports/markuputils/MarkupHelper.java +++ b/src/main/java/com/aventstack/extentreports/markuputils/MarkupHelper.java @@ -1,30 +1,30 @@ package com.aventstack.extentreports.markuputils; public class MarkupHelper { - - public static Markup createLabel(String text, ExtentColor color) { - Label l = new Label(); - l.setText(text); - l.setColor(color); - return l; - } - - public static Markup createCodeBlock(String code) { - CodeBlock cb = new CodeBlock(); - cb.setCodeBlock(code); - return cb; - } - - public static Markup createCodeBlock(String code, CodeLanguage lang) { - CodeBlock cb = new CodeBlock(); - cb.setCodeBlock(code, lang); - return cb; - } - - public static Markup createTable(String[][] data) { - Table t = new Table(); - t.setData(data); - return t; - } - + + public static Markup createLabel(String text, ExtentColor color) { + Label l = new Label(); + l.setText(text); + l.setColor(color); + return l; + } + + public static Markup createCodeBlock(String code) { + CodeBlock cb = new CodeBlock(); + cb.setCodeBlock(code); + return cb; + } + + public static Markup createCodeBlock(String code, CodeLanguage lang) { + CodeBlock cb = new CodeBlock(); + cb.setCodeBlock(code, lang); + return cb; + } + + public static Markup createTable(String[][] data) { + Table t = new Table(); + t.setData(data); + return t; + } + } diff --git a/src/main/java/com/aventstack/extentreports/markuputils/MarkupTemplate.java b/src/main/java/com/aventstack/extentreports/markuputils/MarkupTemplate.java new file mode 100644 index 0000000..f5db943 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/markuputils/MarkupTemplate.java @@ -0,0 +1,10 @@ +package com.aventstack.extentreports.markuputils; + +import com.aventstack.extentreports.ExtentReports; +import com.aventstack.extentreports.templating.FreemarkerTemplate; + +class MarkupTemplate { + + protected static final FreemarkerTemplate ft = new FreemarkerTemplate(ExtentReports.class, "markup/", "UTF-8"); + +} diff --git a/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java b/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java index c1e25a9..d37f432 100644 --- a/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java +++ b/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java @@ -30,8 +30,7 @@ public void saveScreenCapture(BasicMongoReportElement el, ScreenCapture media) t Document doc = new Document("project", klovMedia.getProjectId()) .append("report", klovMedia.getReportId()) .append("sequence", media.getSequence()) - .append("mediaType", media.getMediaType().toString().toLowerCase()) - .append("test", media.getTestObjectId()); + .append("test", media.getBsonId().get("testId")); if (el.getClass() != Test.class) { doc.append("log", el.getObjectId()); @@ -41,9 +40,8 @@ public void saveScreenCapture(BasicMongoReportElement el, ScreenCapture media) t klovMedia.getMediaCollection().insertOne(doc); ObjectId mediaId = MongoUtil.getId(doc); - media.setObjectId(mediaId); - - media.setReportObjectId(klovMedia.getReportId()); + media.getBsonId().put("id", mediaId); + media.getBsonId().put("reportId", klovMedia.getReportId()); mediaStorage.storeMedia((ScreenCapture)media); } diff --git a/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java b/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java index 043777a..5203149 100644 --- a/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java +++ b/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java @@ -16,6 +16,7 @@ import com.aventstack.extentreports.mediastorage.MediaStorage; import com.aventstack.extentreports.model.Media; +import com.aventstack.extentreports.model.ScreenCapture; import com.aventstack.extentreports.utils.FileUtil; public class HttpMediaManagerImplKlov @@ -36,9 +37,12 @@ public void init(String host) throws IOException { @Override public void storeMedia(Media m) throws IOException { - if (m.getPath() == null || m.getBase64String() != null) + if (m.getPath() == null) { return; - + } + if (m instanceof ScreenCapture && ((ScreenCapture)m).getBase64String() != null) { + return; + } File f = new File(m.getPath()); if (!f.exists()) { throw new IOException("The system cannot find the file specified " + m.getPath()); @@ -54,14 +58,13 @@ public void storeMedia(Media m) throws IOException { MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); builder.addPart("name",new StringBody(m.getSequence() + "." + ext, ContentType.TEXT_PLAIN)); - builder.addPart("id", new StringBody(m.getObjectId().toString(), ContentType.TEXT_PLAIN)); - builder.addPart("reportId", new StringBody(m.getReportObjectId().toString(), ContentType.TEXT_PLAIN)); - builder.addPart("testId", new StringBody(m.getTestObjectId().toString(), ContentType.TEXT_PLAIN)); - builder.addPart("mediaType", new StringBody(String.valueOf(m.getMediaType()).toLowerCase(), ContentType.TEXT_PLAIN)); + builder.addPart("id", new StringBody(m.getBsonId().get("id").toString(), ContentType.TEXT_PLAIN)); + builder.addPart("reportId", new StringBody(m.getBsonId().get("reportId").toString(), ContentType.TEXT_PLAIN)); + builder.addPart("testId", new StringBody(m.getBsonId().get("testId").toString(), ContentType.TEXT_PLAIN)); builder.addPart("f", new FileBody(new File(m.getPath()))); post.setEntity(builder.build()); - String logId = m.getLogObjectId() == null ? "" : m.getLogObjectId().toString(); + String logId = m.getBsonId().get("logId") == null ? "" : m.getBsonId().get("logId").toString(); builder.addPart("logId", new StringBody(logId, ContentType.TEXT_PLAIN)); HttpClient client = HttpClientBuilder.create().build(); @@ -76,7 +79,7 @@ public void storeMedia(Media m) throws IOException { } private boolean isResponseValid(int responseCode) { - return 200 <= responseCode && responseCode <= 399; + return responseCode >= 200 && responseCode < 400; } } diff --git a/src/main/java/com/aventstack/extentreports/model/AbstractStructure.java b/src/main/java/com/aventstack/extentreports/model/AbstractStructure.java index 38fd521..356fc13 100644 --- a/src/main/java/com/aventstack/extentreports/model/AbstractStructure.java +++ b/src/main/java/com/aventstack/extentreports/model/AbstractStructure.java @@ -11,12 +11,8 @@ public class AbstractStructure implements Serializable { private static final long serialVersionUID = -2630417398255980331L; - private transient List list; + private List list = Collections.synchronizedList(new ArrayList<>()); - AbstractStructure() { - list = Collections.synchronizedList(new ArrayList<>()); - } - public void add(T t) { list.add(t); } @@ -38,8 +34,9 @@ public List getAll() { } public int size() { - if (list == null) + if (list == null) { return 0; + } return list.size(); } @@ -76,4 +73,4 @@ public void remove() { } } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/Attribute.java b/src/main/java/com/aventstack/extentreports/model/Attribute.java index 2b1e436..77494d7 100644 --- a/src/main/java/com/aventstack/extentreports/model/Attribute.java +++ b/src/main/java/com/aventstack/extentreports/model/Attribute.java @@ -2,36 +2,39 @@ import java.io.Serializable; -abstract class Attribute - implements Serializable { - - private static final long serialVersionUID = 6491172989326625178L; - - private String k; - private String v; - - public Attribute(String k, String v) { - this.k = k; - this.v = v; - } - - public Attribute(String k) { - this(k, null); - } - - protected String getKey() { - return k; - } - - protected void setKey(String k) { - this.k = k; - } - - public String getValue() { - return v; - } - - public void setValue(String v) { - this.v = v; - } -} +public class Attribute implements Serializable { + + private static final long serialVersionUID = 6491172989326625178L; + + private String k; + private String v; + + public Attribute() { + } + + public Attribute(String k, String v) { + this.k = k; + this.v = v; + } + + public Attribute(String k) { + this(k, null); + } + + public String getName() { + return k; + } + + public void setName(String k) { + this.k = k; + } + + public String getValue() { + return v; + } + + public void setValue(String v) { + this.v = v; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/Author.java b/src/main/java/com/aventstack/extentreports/model/Author.java index 3e26b3a..2e3b6b1 100644 --- a/src/main/java/com/aventstack/extentreports/model/Author.java +++ b/src/main/java/com/aventstack/extentreports/model/Author.java @@ -1,12 +1,15 @@ package com.aventstack.extentreports.model; -public class Author - extends TestAttribute { +public class Author extends Attribute { - private static final long serialVersionUID = 5358337504569462439L; + private static final long serialVersionUID = -6374771272610470521L; - public Author(String k) { - super(k); - } - -} + public Author(String k) { + super(k); + } + + public Author(String k, String v) { + super(k, v); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/Category.java b/src/main/java/com/aventstack/extentreports/model/Category.java index a2195ac..f9eb334 100644 --- a/src/main/java/com/aventstack/extentreports/model/Category.java +++ b/src/main/java/com/aventstack/extentreports/model/Category.java @@ -1,12 +1,15 @@ package com.aventstack.extentreports.model; -public class Category - extends TestAttribute { +public class Category extends Attribute { - private static final long serialVersionUID = -7850780488330456977L; + private static final long serialVersionUID = 2652701333761577144L; - public Category(String k) { - super(k); - } - -} + public Category(String k) { + super(k); + } + + public Category(String k, String v) { + super(k, v); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/Device.java b/src/main/java/com/aventstack/extentreports/model/Device.java index 05a99f5..e148219 100644 --- a/src/main/java/com/aventstack/extentreports/model/Device.java +++ b/src/main/java/com/aventstack/extentreports/model/Device.java @@ -1,12 +1,15 @@ package com.aventstack.extentreports.model; -public class Device - extends TestAttribute { +public class Device extends Attribute { - private static final long serialVersionUID = 4823653818257315805L; + private static final long serialVersionUID = -3675996041755598043L; - public Device(String device) { - super(device); + public Device(String k) { + super(k); + } + + public Device(String k, String v) { + super(k, v); } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/ExceptionInfo.java b/src/main/java/com/aventstack/extentreports/model/ExceptionInfo.java index ee05a60..bbadc83 100644 --- a/src/main/java/com/aventstack/extentreports/model/ExceptionInfo.java +++ b/src/main/java/com/aventstack/extentreports/model/ExceptionInfo.java @@ -2,39 +2,31 @@ import java.io.Serializable; -import com.aventstack.extentreports.utils.ExceptionUtil; - public class ExceptionInfo implements Serializable { private static final long serialVersionUID = 2672123037706464734L; private String exceptionName; private String stackTrace; - private Throwable t; - - public ExceptionInfo() { } - - public ExceptionInfo(Throwable t) { - setException(t); - setExceptionName(ExceptionUtil.getExceptionHeadline(t)); - setStackTrace(ExceptionUtil.getStackTrace(t)); - } - - // exception-name - public String getExceptionName() { return exceptionName; } - - public void setExceptionName(String exceptionName) { this.exceptionName = exceptionName; } - - // stack-trace - public String getStackTrace() { return stackTrace; } - - public void setStackTrace(String stackTrace) { - this.stackTrace = stackTrace; - } - - // exception - public void setException(Throwable t) { this.t = t; } - - public Throwable getException() { return t; } - + private Throwable throwable; + + public String getExceptionName() { + return exceptionName; + } + public void setExceptionName(String exceptionName) { + this.exceptionName = exceptionName; + } + public String getStackTrace() { + return stackTrace; + } + public void setStackTrace(String stackTrace) { + this.stackTrace = stackTrace; + } + public Throwable getThrowable() { + return throwable; + } + public void setThrowable(Throwable throwable) { + this.throwable = throwable; + } + } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/ExceptionTestContext.java b/src/main/java/com/aventstack/extentreports/model/ExceptionTestContext.java deleted file mode 100644 index 1d30a1c..0000000 --- a/src/main/java/com/aventstack/extentreports/model/ExceptionTestContext.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aventstack.extentreports.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -public class ExceptionTestContext - implements Serializable { - - private static final long serialVersionUID = -2516200535748363722L; - - private ExceptionInfo exceptionInfo; - private List testList = new ArrayList<>(); - - public ExceptionTestContext(ExceptionInfo exceptionInfo) { - this.exceptionInfo = exceptionInfo; - } - - public void setTest(Test test) { - testList.add(test); - } - - public List getTestList() { - return testList; - } - - public ExceptionInfo getExceptionInfo() { - return exceptionInfo; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/model/IAddsMedia.java b/src/main/java/com/aventstack/extentreports/model/IAddsMedia.java deleted file mode 100644 index 87d95d3..0000000 --- a/src/main/java/com/aventstack/extentreports/model/IAddsMedia.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.aventstack.extentreports.model; - -import java.io.IOException; - -public interface IAddsMedia { - - /** - * Adds a snapshot to the test or log with title - * - * @param imagePath Image path - * @param title Image title - * - * @return Object this method is called from, generally {@link com.aventstack.extentreports.ExtentTest} or {@link Log} - * - * @throws IOException thrown if the imagePath of image is not found - */ - T addScreenCaptureFromPath(String imagePath, String title) throws IOException; - - /** - * Adds a snapshot to test or log - * - * @param imagePath Image path - * - * @return Object this method is called from, generally {@link com.aventstack.extentreports.ExtentTest} or {@link Log} - * - * @throws IOException thrown if the imagePath of image is not found - */ - T addScreenCaptureFromPath(String imagePath) throws IOException; - - /** - * Adds a base64 screenshot - * - * @param s base64 string - * @param title Image title - * - * @return Object this method is called from, generally {@link com.aventstack.extentreports.ExtentTest} or {@link Log} - */ - T addScreenCaptureFromBase64String(String s, String title); - - /** - * Adds a base64 screenshot - * - * @param s base64 string - * - * @return Object this method is called from, generally {@link com.aventstack.extentreports.ExtentTest} or {@link Log} - */ - T addScreenCaptureFromBase64String(String s); - - /** - * Adds a screencast to test or log - * - * @param screencastPath Screencast path - * - * @return Object this method is called from, generally {@link com.aventstack.extentreports.ExtentTest} or {@link Log} - * - * @throws IOException thrown if the screencastPath of image is not found - */ - T addScreencastFromPath(String screencastPath) throws IOException; -} diff --git a/src/main/java/com/aventstack/extentreports/model/Log.java b/src/main/java/com/aventstack/extentreports/model/Log.java index 204d2d0..7ebb249 100644 --- a/src/main/java/com/aventstack/extentreports/model/Log.java +++ b/src/main/java/com/aventstack/extentreports/model/Log.java @@ -4,149 +4,82 @@ import java.util.Calendar; import java.util.Date; -import org.bson.types.ObjectId; - -import com.aventstack.extentreports.ExtentTest; import com.aventstack.extentreports.RunResult; import com.aventstack.extentreports.Status; -import com.aventstack.extentreports.markuputils.Markup; - -public class Log - implements RunResult, Serializable, BasicMongoReportElement { - - private static final long serialVersionUID = 1594512136869286425L; - - private AbstractStructure screenCaptureContext; - private AbstractStructure screencastContext; - private ExtentTest parent; - private Test parentModel; - private Markup markup; - private Date timestamp = Calendar.getInstance().getTime(); - private Status logStatus; - private String stepName; - private String details; - private int sequence; - private ObjectId objectId; - private ExceptionInfo exceptionInfo; - - public Log(Test test) { - this.parentModel = test; - } - - public Log(ExtentTest test) { - this.parent = test; - } - - public Date getTimestamp() { - return timestamp; - } - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } - - public void setStatus(Status logStatus) { - this.logStatus = logStatus; - } - public Status getStatus() { - return logStatus; - } - - public void setStepName(String stepName) { - this.stepName = stepName; - } - public String getStepName() { - return stepName; - } - - public void setDetails(String details) { - this.details = details; - } - public String getDetails() { - return details; - } - - public void setMarkup(Markup markup) { - this.markup = markup; - } - public Markup getMarkup() { - return markup; - } - - public void setSequence(int sequence) { - this.sequence = sequence; - } - public int getSequence() { - return sequence; - } - - public void setScreenCapture(ScreenCapture screenCapture) { - if (screenCaptureContext == null) { - screenCaptureContext = new AbstractStructure<>(); - } - screenCaptureContext.add(screenCapture); - screenCapture.setTestObjectId(getParent().getModel().getObjectId()); - } - - public AbstractStructure getScreenCaptureContext() { - return screenCaptureContext; - } - - public boolean hasScreenCapture() { - return screenCaptureContext != null - && screenCaptureContext.size() > 0; - } - - public void setScreencast(Screencast screencast) { - if (screencastContext == null) { - screencastContext = new AbstractStructure<>(); - } - screencastContext.add(screencast); - } - - public AbstractStructure getScreencastContext() { - return screencastContext; - } - - public boolean hasScreencast() { - return screencastContext != null - && screencastContext.size() > 0; - } - - public ExtentTest getParent() { - return parent; - } - - public Test getParentModel() { - return parent == null - ? parentModel - : parent.getModel(); - } - - @Override - public ObjectId getObjectId() { - return objectId; - } - - @Override - public void setObjectId(ObjectId id) { - objectId = id; - } - - public void setExceptionInfo(ExceptionInfo exceptionInfo) { - this.exceptionInfo = exceptionInfo; - } - - public ExceptionInfo getExceptionInfo() { - return exceptionInfo; - } - - @Override - public String toString() { - return "[log] " + - " {timestamp: " + getTimestamp() + "," + - " status: " + getStatus() + "," + - " details: " + getDetails() + - " }"; - } - -} \ No newline at end of file + +public class Log implements Serializable, RunResult { + + private static final long serialVersionUID = 8072065800800347981L; + private Date timestamp = Calendar.getInstance().getTime(); + + private ExceptionInfo exceptionInfo; + private AbstractStructure screenCapture; + private transient Test test; + private Status status; + private String details; + private int sequence; + + public Log(Test test) { + this.test = test; + } + + public Date getTimestamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public ExceptionInfo getExceptionInfo() { + return exceptionInfo; + } + + public void setExceptionInfo(ExceptionInfo exceptionInfo) { + this.exceptionInfo = exceptionInfo; + } + + public AbstractStructure getScreenCapture() { + if (screenCapture == null) { + screenCapture = new AbstractStructure<>(); + } + return screenCapture; + } + + public void setScreenCapture(AbstractStructure screenCapture) { + this.screenCapture = screenCapture; + } + + public Test getTest() { + return test; + } + + public void setTest(Test test) { + this.test = test; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public int getSequence() { + return sequence; + } + + public void setSequence(int sequence) { + this.sequence = sequence; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/model/Media.java b/src/main/java/com/aventstack/extentreports/model/Media.java index f87ea9e..6988aaf 100644 --- a/src/main/java/com/aventstack/extentreports/model/Media.java +++ b/src/main/java/com/aventstack/extentreports/model/Media.java @@ -1,119 +1,70 @@ package com.aventstack.extentreports.model; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import org.bson.types.ObjectId; -import com.aventstack.extentreports.utils.FileUtil; - -public class Media - implements Serializable { - - private static final long serialVersionUID = -5706630485211806728L; - - private ObjectId id; - private ObjectId reportId; - private ObjectId testId; - private ObjectId logId; - private String name; - private String description; - private String path; - private String base64String; - private int seq; - private long fileSize = 0; - - private MediaType mediaType; - - public void setObjectId(ObjectId id) { - this.id = id; - } - - public ObjectId getObjectId() { - return id; +public class Media implements Serializable { + + private static final long serialVersionUID = 2620739620884939951L; + private String name; + private String description; + private String path; + private int sequence; + private long fileSize = 0; + private Map bsonId; + + public String getName() { + return name; } - - public void setReportObjectId(ObjectId reportId) { - this.reportId = reportId; - } - - public ObjectId getReportObjectId() { - return reportId; + + public void setName(String name) { + this.name = name; } - public void setTestObjectId(ObjectId testId) { - this.testId = testId; - } - - public ObjectId getTestObjectId() { - return testId; + public String getDescription() { + return description; } - - public void setLogObjectId(ObjectId logId) { - this.logId = logId; - } - - public ObjectId getLogObjectId() { - return logId; + + public void setDescription(String description) { + this.description = description; } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; + + public String getPath() { + return path; } - - protected void setDescription(String description) { - this.description = description; - } - - protected String getDescription() { - return description; + + public void setPath(String path) { + this.path = path; } - - public void setPath(String path) { - this.path = path; - setFileSize(FileUtil.getFileSize(path)); - if (getName() == null || getName().isEmpty()) - setName(FileUtil.getFileName(path)); - } - - public String getPath() { - return path; + + public int getSequence() { + return sequence; } - public long getFileSize() { - return fileSize; - } + public void setSequence(int sequence) { + this.sequence = sequence; + } - public void setFileSize(long fileSize) { - this.fileSize = fileSize; - } + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } - public void setMediaType(MediaType mediaType) { - this.mediaType = mediaType; - } - - public MediaType getMediaType() { - return mediaType; + public Map getBsonId() { + if (bsonId == null) { + bsonId = new HashMap<>(); + } + return bsonId; } - public void setSequence(int seq) { - this.seq = seq; - } - - public int getSequence() { - return seq; + public void setBsonId(Map bsonId) { + this.bsonId = bsonId; } - public void setBase64String(String string) { - string = string.contains("data:") || string.contains("image/") ? string : "data:image/png;base64," + string; - this.base64String = string; - } - - public String getBase64String() { - return base64String; - } - } diff --git a/src/main/java/com/aventstack/extentreports/model/MediaType.java b/src/main/java/com/aventstack/extentreports/model/MediaType.java deleted file mode 100644 index 6163475..0000000 --- a/src/main/java/com/aventstack/extentreports/model/MediaType.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.aventstack.extentreports.model; - -public enum MediaType { - IMG, - VID -} diff --git a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java index 1021c4a..40c6df8 100644 --- a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java +++ b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java @@ -1,26 +1,23 @@ package com.aventstack.extentreports.model; -public class ScreenCapture - extends Media { +public class ScreenCapture extends Media { - private static final long serialVersionUID = -3413285738443448335L; + private static final long serialVersionUID = 3876935785138278521L; + private String base64; - public String getSource() { - if (getBase64String() != null) - return "base64-img"; + public String getBase64String() { + return base64; + } - return ""; - } - - public String getSourceWithIcon() { - return "img"; - } - - public String getScreenCapturePath() { - return getPath() != null ? getPath() : getBase64String(); - } + public void setBase64String(String base64) { + this.base64 = base64; + } - public Boolean isBase64() { - return getBase64String() != null; - } -} \ No newline at end of file + public String getScreenCapturePath() { + return getPath() != null ? getPath() : getBase64String(); + } + + public Boolean isBase64() { + return getBase64String() != null; + } +} diff --git a/src/main/java/com/aventstack/extentreports/model/Screencast.java b/src/main/java/com/aventstack/extentreports/model/Screencast.java deleted file mode 100644 index e3c3c81..0000000 --- a/src/main/java/com/aventstack/extentreports/model/Screencast.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.aventstack.extentreports.model; - -public class Screencast - extends Media { - - private static final long serialVersionUID = -3413285738443448335L; - - public String getSource() { - return ""; - } - - public String getSourceWithIcon() { - return getSource(); - } - -} diff --git a/src/main/java/com/aventstack/extentreports/model/SystemAttribute.java b/src/main/java/com/aventstack/extentreports/model/SystemAttribute.java index 13baa26..27ed149 100644 --- a/src/main/java/com/aventstack/extentreports/model/SystemAttribute.java +++ b/src/main/java/com/aventstack/extentreports/model/SystemAttribute.java @@ -1,20 +1,15 @@ package com.aventstack.extentreports.model; -public class SystemAttribute - extends Attribute { +public class SystemAttribute extends Attribute { - private static final long serialVersionUID = 7531709191041382750L; + private static final long serialVersionUID = -6374771272610470521L; - public SystemAttribute(String k, String v) { - super(k, v); - } - - public String getName() { - return getKey(); - } - - public void setName(String name) { - setKey(name); - } + public SystemAttribute(String k) { + super(k); + } -} + public SystemAttribute(String k, String v) { + super(k, v); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index da90311..d89e200 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -1,511 +1,365 @@ package com.aventstack.extentreports.model; import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Calendar; import java.util.Date; -import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import org.bson.types.ObjectId; - import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.RunResult; import com.aventstack.extentreports.Status; import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel; +import com.google.gson.annotations.Expose; + +public class Test implements Serializable, RunResult { + + private static final long serialVersionUID = -8681630689550647312L; + private static final AtomicInteger atomicInt = new AtomicInteger(0); + + /** + * An instance of {@link ExtentReports} + */ + private transient ExtentReports extent; + + /** + * Level describes the hierarchy of the test in the tree. A level 0 indicates a + * parent test. Level 1 indicates an immediate child of the parent, level 2 + * indicates an immediate child of the Child and so on.. The bottom-most test in + * the hierarchy is considered a leaf + */ + private int level = 0; + + /** + * A unique ID, generated by AtomicInteger + */ + private transient int id = atomicInt.incrementAndGet(); + + /** + * If this Test is at the top-most level, or in other words, has a level value + * of 0, parent will be null. This field will only contain a value if the Test + * is a child, or has a level 1 or greater. + */ + private transient Test parent; + + /** + * {@link Status} of this test, defaults to PASS + */ + private Status status = Status.PASS; + + /** + * A structure containing all nodes of this test + */ + private AbstractStructure nodeContext; + + /** + * A structure containing all logs/events of this test + */ + private AbstractStructure logContext; + + /** + * A structure containing all categories assigned to this test + */ + private AbstractStructure categoryContext; + + /** + * A structure containing all authors assigned to this test + */ + private AbstractStructure authorContext; + + /** + * A structure containing all devices assigned to this test + */ + private AbstractStructure deviceContext; + + /** + * Time the test was started + */ + private Date startTime = Calendar.getInstance().getTime(); + + /** + * Time the test was ended + */ + private Date endTime = Calendar.getInstance().getTime(); + + /** + * Type of BDD object represented by {@link IGherkinFormatterModel}. It can have + * one of the following values: + * + *
      + *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • + *
    • {@link com.aventstack.extentreports.gherkin.model.But}
    • + *
    + */ + private transient Class bddType; + + @Expose + private String bddTypeName; + + /** + * A list of {@link ScreenCapture} + */ + private transient AbstractStructure screenCaptureContext; + + /** + * A list of {@link ExceptionInfo} + */ + private transient AbstractStructure exceptionInfoContext; + + /** + * Name of the test + */ + private String name; + + /** + * Description + */ + private String description; + + /** + * This setting allows setting test with your own time-stamps. With this + * enabled, Extent does not use time-stamps for tests at the time they were + * created + */ + private boolean usesManualConfiguration = false; + + public ExtentReports getExtent() { + return extent; + } + + public void setExtent(ExtentReports extent) { + this.extent = extent; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Test getParent() { + return parent; + } + + public void setParent(Test parent) { + this.parent = parent; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public AbstractStructure getNodeContext() { + if (nodeContext == null) { + nodeContext = new AbstractStructure<>(); + } + return nodeContext; + } + + public void setNodeContext(AbstractStructure node) { + this.nodeContext = node; + } + + public AbstractStructure getLogContext() { + if (logContext == null) { + logContext = new AbstractStructure<>(); + } + return logContext; + } + + public void setLogContext(AbstractStructure log) { + this.logContext = log; + } + + public AbstractStructure getCategoryContext() { + if (categoryContext == null) { + categoryContext = new AbstractStructure<>(); + } + return categoryContext; + } + + public void setCategoryContext(AbstractStructure category) { + this.categoryContext = category; + } + + public AbstractStructure getAuthorContext() { + if (authorContext == null) { + authorContext = new AbstractStructure<>(); + } + return authorContext; + } -public class Test - implements BasicMongoReportElement, RunResult, Serializable { - - private static final long serialVersionUID = 5590943223572254960L; - private static final AtomicInteger atomicInt = new AtomicInteger(0); - - /** - * An instance of {@link ExtentReports} - */ - private transient ExtentReports extent; - - /** - * Level describes the hierarchy of the test in the tree. A level 0 indicates a parent - * test. Level 1 indicates an immediate child of the parent, level 2 indicates an immediate - * child of the Child and so on.. The bottom-most test in the hierarchy is considered - * a leaf - */ - private int level = 0; - - /** - * A unique ID, generated by AtomicInteger - */ - private int testId = atomicInt.incrementAndGet(); - - /** - * If this Test is at the top-most level, or in other words, has a level value of 0, parent - * will be null. This field will only contain a value if the Test is a child, or has a level - * 1 or greater. - */ - private Test parent; - - /** - * {@link Status} of this test, defaults to PASS - */ - private Status status = Status.PASS; - - /** - * A structure containing all nodes of this test - */ - private AbstractStructure node; - - /** - * A structure containing all logs/events of this test - */ - private AbstractStructure log; - - /** - * A structure containing all categories assigned to this test - */ - private AbstractStructure category; - - /** - * A structure containing all authors assigned to this test - */ - private AbstractStructure author; - - /** - * A structure containing all devices assigned to this test - */ - private AbstractStructure device; - - /** - * Time the test was started - */ - private Date startTime = Calendar.getInstance().getTime(); - - /** - * Time the test was ended - */ - private Date endTime = Calendar.getInstance().getTime(); - - /** - * An assigned {@link ObjectId} - */ - private ObjectId mongoId; - - /** - * Type of BDD object represented by {@link IGherkinFormatterModel}. It can have one - * of the following values: - * - *
      - *
    • {@link com.aventstack.extentreports.gherkin.model.Feature}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Background}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Scenario}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Given}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.When}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.Then}
    • - *
    • {@link com.aventstack.extentreports.gherkin.model.And}
    • - *
    - */ - private Class bddType; - - /** - * A list of {@link ScreenCapture} - */ - private transient List screenCaptureList; - - /** - * A list of {@link Screencast} - */ - private transient List screencastList; - - /** - * A list of {@link ExceptionInfo} - */ - private transient List exceptionList; - - /** - * Name of the test - */ - private String name; - - /** - * Hierarchical name of the test - * - *

    - * Note: This field will equal the name if the test is the top-most level. - * - *

    - * For tests having level 1 or greater, the hierarchical name would be separated by - * a dot character as: - * - * Test.Child.GrandChild - */ - private String hierarchicalName; - - /** - * Description - */ - private String description; - - /** - * Indicates if the test has ended - */ - private boolean ended = false; - - /** - * This setting allows setting test with your own time-stamps. With this enabled, Extent - * does not use time-stamps for tests at the time they were created - */ - private boolean usesManualConfiguration = false; - - - // if used via listener, allow manual configuration of model - public void setUseManualConfiguration(boolean b) { - this.usesManualConfiguration = b; - } - - public ExtentReports getExtentInstance() { - return extent; - } - - public void setExtentInstance(ExtentReports extent) { - this.extent = extent; - } - - public boolean isChildNode() { - return level > 0; - } - - public int getLevel() { - return level; - } - - public void setLevel(int level) { - this.level = level; - } - - public void setParent(Test parent) { - this.parent = parent; - } - - public Test getParent() { return parent; } - - public AbstractStructure getChildrenNodes() { - if (node == null) { - node = new AbstractStructure<>(); - } - - return node; - } - - public boolean hasChildren() { - return node != null && !node.isEmpty(); - } - - public void addChildNode(Test childTest) { - getChildrenNodes().add(childTest); - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - public Date getStartTime() { - return startTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - private void setEndTimeFromChildren() { - if (hasChildren()) { - setStartTime(getChildrenNodes().getFirst().getStartTime()); - setEndTime(getChildrenNodes().getLast().getEndTime()); - } else if (hasLog()) { - Date lastLogEndTime = getLogContext().getLast().getTimestamp(); - setEndTime(lastLogEndTime); - } - } - - public Date getEndTime() { - return endTime; - } - - public boolean hasEnded() { - return ended; - } - - public String getRunDuration() { - long diff = endTime.getTime() - startTime.getTime(); - - long secs = diff / 1000; - long millis = diff % 1000; - long mins = secs / 60; - secs = secs % 60; - long hours = mins / 60; - mins = mins % 60; - - return hours + "h " + mins + "m " + secs + "s+" + millis + "ms"; - } - - public Long getRunDurationMillis() { - return endTime.getTime() - startTime.getTime(); - } - - // default status when the test starts - public void setStatus(Status status) { - this.status = status; - } - - public Status getStatus() { - return status; - } - - public void trackLastRunStatus() { - getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); - - status = (status == Status.INFO || status == Status.DEBUG) - ? Status.PASS - : status; - } - - private synchronized void updateStatus(Status logStatus) { - int logStatusIndex = Status.getStatusHierarchy().indexOf(logStatus); - int testStatusIndex = Status.getStatusHierarchy().indexOf(status); - - status = logStatusIndex < testStatusIndex ? logStatus : status; - } - - public void end() { - updateTestStatusRecursive(this); - endChildrenRecursive(this); - - status = (status == Status.INFO || status == Status.DEBUG) - ? Status.PASS - : status; - - if (!usesManualConfiguration) - setEndTimeFromChildren(); - } - - private synchronized void updateTestStatusRecursive(Test test) { - // Update this test first, based on the logs - test.getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); - - - // Recursively update the status of all the children in the tree - if (test.hasChildren()) { - test.getChildrenNodes().getAll().forEach(this::updateTestStatusRecursive); // First recursion here - } - - // At this point the subtree should be updated. Now we have to update the status - // of current node. - test.getChildrenNodes().getAll().forEach(x -> updateStatus(x.getStatus())); - } - - private void endChildrenRecursive(Test test) { - test.getChildrenNodes().getAll().forEach(Test::end); - } - - public AbstractStructure getLogContext() { - if (log == null) { - log = new AbstractStructure<>(); - } - return log; - } - - public boolean hasLog() { - return log != null && !log.isEmpty(); - } - - public void setDescription(String description) { - this.description = description; - } - - public String getDescription() { return description; } - - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public String getHierarchicalName() { - hierarchicalName = parent == null - ? name - : String.join(".", parent.getHierarchicalName(), getName()); - return hierarchicalName; - } - - public boolean hasAttributes() { - return hasAuthor() || hasCategory() || hasDevice(); - } - - public AbstractStructure getCategoryContext() { - if (category == null) { - category = new AbstractStructure<>(); - } - return category; - } - - public boolean hasCategory(String name) { - return hasCategory() - && category.getAll() - .stream() - .anyMatch(x -> x.getName().equals(name)); - } - - public boolean hasCategoryNode(String name) { - return getChildrenNodes().getAll() - .stream() - .anyMatch(x -> x.hasCategory(name)); - } - - public boolean hasCategory() { - return category != null && !category.isEmpty(); - } - - public void setCategory(TestAttribute category) { - getCategoryContext().add(category); - } - - public TestAttribute getCategory(Integer index) { - if (hasCategory() && index < category.size()) { - return category.get(index); - } - return null; - } - - public AbstractStructure getAuthorContext() { - if (author == null) { - author = new AbstractStructure<>(); - } - return author; - } - - public boolean hasAuthor() { - return author != null && !author.isEmpty(); - } - - public void setAuthor(TestAttribute author) { - getAuthorContext().add(author); - } - - public TestAttribute getAuthor(Integer index) { - if (hasAuthor() && index < author.size()) { - return author.get(index); - } - return null; - } - - public AbstractStructure getDeviceContext() { - if (device == null) { - device = new AbstractStructure<>(); - } - return device; - } - - public boolean hasDevice() { - return device != null && !device.isEmpty(); - } - - public void setDevice(TestAttribute device) { - getDeviceContext().add(device); - } - - public TestAttribute getDevice(Integer index) { - if (hasDevice() && index < author.size()) { - return device.get(index); - } - return null; - } - - public void setExceptionInfo(ExceptionInfo exceptionInfo) { - if (exceptionList == null) { - exceptionList = new ArrayList<>(); - } - exceptionList.add(exceptionInfo); - } - - public List getExceptionInfoList() { - return exceptionList; - } - - public boolean hasException() { - return exceptionList != null && !exceptionList.isEmpty(); - } - - public boolean hasMedia() { - return screenCaptureList != null - && !screenCaptureList.isEmpty() - && screencastList != null - && !screencastList.isEmpty(); - } - - public void setScreenCapture(ScreenCapture screenCapture) { - if (screenCaptureList == null) { - screenCaptureList = new ArrayList<>(); - } - screenCaptureList.add(screenCapture); - } - - public List getScreenCaptureList() { - return screenCaptureList; - } - - public Boolean hasScreenCapture() { - return screenCaptureList != null && !screenCaptureList.isEmpty(); - } - - public void setScreencast(Screencast screencast) { - if (screencastList == null) { - screencastList = new ArrayList<>(); - } - screencastList.add(screencast); - } - - public List getScreencastList() { - return screencastList; - } - - public boolean isBehaviorDrivenType() { - return bddType != null; - } - - public void setBehaviorDrivenType(IGherkinFormatterModel type) { - bddType = type.getClass(); - } - - public void setBehaviorDrivenType(Class type) { - bddType = type; - } - - public Class getBehaviorDrivenType() { - return bddType; - } - - public String getBehaviorDrivenTypeName() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Method method = bddType.getMethod("getGherkinName"); - Object o = method.invoke(null, (Object[]) null); - return o.toString(); - } - - void setID(int id) { - testId = id; - } - - public int getID() { - return testId; - } - - public void setObjectId(ObjectId id) { - mongoId = id; - } - - public ObjectId getObjectId() { - return mongoId; + public void setAuthorContext(AbstractStructure author) { + this.authorContext = author; } + + public AbstractStructure getDeviceContext() { + if (deviceContext == null) { + deviceContext = new AbstractStructure<>(); + } + return deviceContext; + } + + public void setDeviceContext(AbstractStructure device) { + this.deviceContext = device; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public Class getBddType() { + return bddType; + } + + public void setBddType(Class bddType) { + this.bddType = bddType; + bddTypeName = getBehaviorDrivenTypeName(); + } + + public AbstractStructure getScreenCaptureContext() { + if (screenCaptureContext == null) { + screenCaptureContext = new AbstractStructure<>(); + } + return screenCaptureContext; + } + + public void setScreenCaptureContext(AbstractStructure screenCapture) { + this.screenCaptureContext = screenCapture; + } + + public AbstractStructure getExceptionInfoContext() { + if (exceptionInfoContext == null) { + exceptionInfoContext = new AbstractStructure<>(); + } + return exceptionInfoContext; + } + + public void setExceptionInfoContext(AbstractStructure exception) { + this.exceptionInfoContext = exception; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isUsesManualConfiguration() { + return usesManualConfiguration; + } + + public void setUsesManualConfiguration(boolean usesManualConfiguration) { + this.usesManualConfiguration = usesManualConfiguration; + } + + private synchronized void updateStatus(Status logStatus) { + int logStatusIndex = Status.getStatusHierarchy().indexOf(logStatus); + int testStatusIndex = Status.getStatusHierarchy().indexOf(status); + + status = logStatusIndex < testStatusIndex ? logStatus : status; + } + + public void end() { + updateTestStatusRecursive(this); + endChildrenRecursive(this); + status = (status == Status.INFO || status == Status.DEBUG) ? Status.PASS : status; + if (!usesManualConfiguration) { + setEndTimeFromChildren(); + } + } + + private synchronized void updateTestStatusRecursive(Test test) { + test.getLogContext().getAll().forEach(x -> updateStatus(x.getStatus())); + + if (!test.getNodeContext().isEmpty()) { + test.getNodeContext().getAll().forEach(this::updateTestStatusRecursive); + } + + // if not all children are marked SKIP, then: + // ensure the parent has a status that is not SKIP + if (test.bddType == null) { + boolean hasNodeNotSkipped = test.getNodeContext().getAll().stream() + .anyMatch(x -> x.getStatus() != Status.SKIP); + + if (status == Status.SKIP && hasNodeNotSkipped) { + // reset status + status = Status.PASS; + // compute new status + test.getNodeContext().getAll().stream().filter(x -> x.getStatus() != Status.SKIP) + .forEach(this::updateTestStatusRecursive); + } + } + } + + private void endChildrenRecursive(Test test) { + test.getNodeContext().getAll().forEach(Test::end); + } + + private void setEndTimeFromChildren() { + if (!getNodeContext().isEmpty()) { + setStartTime(getNodeContext().getFirst().getStartTime()); + setEndTime(getNodeContext().getLast().getEndTime()); + } else if (!getLogContext().isEmpty()) { + Date lastLogEndTime = getLogContext().getLast().getTimestamp(); + setEndTime(lastLogEndTime); + } + } + + public String getBehaviorDrivenTypeName() { + try { + Method method = bddType.getMethod("getGherkinName"); + Object o = method.invoke(null, (Object[]) null); + return o.toString(); + } catch (Exception e) { + return null; + } + } + + public Boolean isBehaviorDrivenType() { + return getBddType() != null; + } + } diff --git a/src/main/java/com/aventstack/extentreports/model/TestAttribute.java b/src/main/java/com/aventstack/extentreports/model/TestAttribute.java deleted file mode 100644 index 1d6fe70..0000000 --- a/src/main/java/com/aventstack/extentreports/model/TestAttribute.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aventstack.extentreports.model; - -import java.io.Serializable; - -public abstract class TestAttribute - extends Attribute - implements Serializable { - - static final long serialVersionUID = 1010210091204302766L; - - public TestAttribute(String k) { - super(k); - } - - public String getName() { - return getKey(); - } - - public void setName(String name) { - setKey(name); - } - - public String getDescription() { - return getValue(); - } - - public void setDescription(String description) { - setValue(description); - } - -} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/TestAttributeTestContext.java b/src/main/java/com/aventstack/extentreports/model/TestAttributeTestContext.java deleted file mode 100644 index be32402..0000000 --- a/src/main/java/com/aventstack/extentreports/model/TestAttributeTestContext.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.aventstack.extentreports.model; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import com.aventstack.extentreports.Status; - -public class TestAttributeTestContext - implements Serializable { - - private static final long serialVersionUID = 2595632998970711190L; - - private T testAttribute; - private List testList = new ArrayList<>(); - private int passed = 0; - private int failed = 0; - private int skip = 0; - private int others = 0; - - public TestAttributeTestContext(T testAttribute) { - this.testAttribute = testAttribute; - } - - public void setTest(Test test) { - updateTestStatusCounts(test); - testList.add(test); - } - - private void updateTestStatusCounts(Test test) { - passed += test.getStatus() == Status.PASS ? 1 : 0; - failed += test.getStatus() == Status.FAIL || test.getStatus() == Status.FATAL ? 1 : 0; - skip += test.getStatus() == Status.SKIP ? 1 : 0; - others += test.getStatus() != Status.PASS - && test.getStatus() != Status.FATAL - && test.getStatus() != Status.FAIL - && test.getStatus() != Status.SKIP? 1 : 0; - } - - public void refreshTestStatusCounts() { - passed = 0; - failed = 0; - skip = 0; - others = 0; - testList.forEach(this::updateTestStatusCounts); - } - - public List getTestList() { - return testList; - } - - public String getName() { - return testAttribute.getName(); - } - - public int getPassed() { - return passed; - } - - public int getFailed() { - return failed; - } - - public int getSkipped() { - return skip; - } - - public int getOthers() { - return others; - } - - public int size() { - return testList == null ? 0 : testList.size(); - } - - public boolean isEmpty() { - return size() == 0; - } - - public T getAttribute() { - return testAttribute; - } -} - diff --git a/src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContext.java b/src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContext.java new file mode 100644 index 0000000..7080bd9 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContext.java @@ -0,0 +1,33 @@ +package com.aventstack.extentreports.model.context; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.aventstack.extentreports.model.ExceptionInfo; +import com.aventstack.extentreports.model.Test; + +public class ExceptionTestContext implements Serializable { + + private static final long serialVersionUID = -2516200535748363722L; + + private ExceptionInfo exceptionInfo; + private List tests = new ArrayList<>(); + + public ExceptionTestContext(ExceptionInfo exceptionInfo) { + this.exceptionInfo = exceptionInfo; + } + + public void setTest(Test test) { + tests.add(test); + } + + public List getTests() { + return tests; + } + + public ExceptionInfo getExceptionInfo() { + return exceptionInfo; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContextStore.java b/src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContextStore.java new file mode 100644 index 0000000..b15dea3 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/context/ExceptionTestContextStore.java @@ -0,0 +1,41 @@ +package com.aventstack.extentreports.model.context; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.aventstack.extentreports.model.ExceptionInfo; +import com.aventstack.extentreports.model.Test; + +/** + * Provides and tracks the collection of tests segregated by the type of + * {@link Exception} + * + */ +public class ExceptionTestContextStore { + + private List exceptionTestContext = new ArrayList<>(); + + public void setExceptionContext(ExceptionInfo ei, Test test) { + Optional exOptionalTestContext = exceptionTestContext.stream() + .filter(x -> x.getExceptionInfo().getExceptionName().equals(ei.getExceptionName())).findFirst(); + + if (exOptionalTestContext.isPresent()) { + List testList = exOptionalTestContext.get().getTests(); + + boolean b = testList.stream().anyMatch(t -> t.getId() == test.getId()); + + if (!b) { + exOptionalTestContext.get().setTest(test); + } + } else { + ExceptionTestContext exTestContext = new ExceptionTestContext(ei); + exTestContext.setTest(test); + exceptionTestContext.add(exTestContext); + } + } + + public List getExceptionTestContext() { + return exceptionTestContext; + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/context/SystemAttributeContext.java b/src/main/java/com/aventstack/extentreports/model/context/SystemAttributeContext.java new file mode 100644 index 0000000..5de8207 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/context/SystemAttributeContext.java @@ -0,0 +1,35 @@ +package com.aventstack.extentreports.model.context; + +import java.util.ArrayList; +import java.util.List; + +import com.aventstack.extentreports.model.SystemAttribute; + +/** + * A simple key-value pair collection to store System/Environment information + * + */ +public class SystemAttributeContext { + + private List list = new ArrayList<>(); + + public void setSystemAttribute(SystemAttribute sa) { + list.add(sa); + } + + public String getSystemAttribute(String k) { + return list.stream() + .filter(x -> x.getName().equals(k)) + .map(SystemAttribute::getValue) + .findFirst() + .orElse(null); + } + + public List getSystemAttributeList() { + return list; + } + + public void clear() { + list.clear(); + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContext.java b/src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContext.java new file mode 100644 index 0000000..9354028 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContext.java @@ -0,0 +1,84 @@ +package com.aventstack.extentreports.model.context; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.aventstack.extentreports.Status; +import com.aventstack.extentreports.model.Attribute; +import com.aventstack.extentreports.model.Test; + +public class TestAttributeTestContext implements Serializable { + + private static final long serialVersionUID = 2595632998970711190L; + + private List tests = new ArrayList<>(); + private T attr; + private int passed = 0; + private int failed = 0; + private int skipped = 0; + private int others = 0; + + public TestAttributeTestContext(T attr) { + this.attr = attr; + } + + public void setTest(Test test) { + updateTestStatusCounts(test); + tests.add(test); + } + + private void updateTestStatusCounts(Test test) { + if (test.getStatus() == Status.PASS) { + passed++; + } else if (test.getStatus() == Status.FAIL || test.getStatus() == Status.FATAL) { + failed++; + } else if (test.getStatus() == Status.SKIP) { + skipped++; + } else { + others++; + } + } + + public void refreshTestStatusCounts() { + passed = failed = skipped = others = 0; + tests.forEach(this::updateTestStatusCounts); + } + + public List getTests() { + return tests; + } + + public String getName() { + return attr.getName(); + } + + public int getPassed() { + return passed; + } + + public int getFailed() { + return failed; + } + + public int getSkipped() { + return skipped; + } + + public int getOthers() { + return others; + } + + public int size() { + return tests == null ? 0 : tests.size(); + } + + public boolean isEmpty() { + return size() == 0; + } + + public T getAttribute() { + return attr; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContextStore.java b/src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContextStore.java new file mode 100644 index 0000000..d3029e3 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/context/TestAttributeTestContextStore.java @@ -0,0 +1,62 @@ +package com.aventstack.extentreports.model.context; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; + +import com.aventstack.extentreports.model.Attribute; +import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.helpers.TestRemover; + +/** + * Uses an attribute context for {@link TestAttribute} (Category, Device, Author + * etc.) and tracks the collection of tests segregated by the type + * {@link TestAttribute} + * + * @param A {@link TestAttribute} type + */ +public class TestAttributeTestContextStore { + + private List> testAttrTestContext; + + public TestAttributeTestContextStore() { + testAttrTestContext = new ArrayList<>(); + } + + public void setAttributeContext(T attr, Test test) { + Optional> optTestContext = testAttrTestContext.stream() + .filter(x -> x.getName().equals(attr.getName())).findFirst(); + + if (optTestContext.isPresent()) { + List tests = optTestContext.get().getTests(); + + boolean b = tests.stream().anyMatch(t -> t.getId() == test.getId()); + + if (!b) { + optTestContext.get().setTest(test); + } + optTestContext.get().refreshTestStatusCounts(); + } else { + TestAttributeTestContext testAttrContext = new TestAttributeTestContext<>(attr); + testAttrContext.setTest(test); + testAttrTestContext.add(testAttrContext); + } + } + + public synchronized void removeTest(Test test) { + Iterator> iter = testAttrTestContext.iterator(); + while (iter.hasNext()) { + TestAttributeTestContext context = iter.next(); + TestRemover.remove(context.getTests(), test); + if (context.isEmpty()) { + iter.remove(); + } + } + } + + public List> getTestAttributeTestContext() { + return testAttrTestContext; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/context/helpers/TestRemover.java b/src/main/java/com/aventstack/extentreports/model/context/helpers/TestRemover.java new file mode 100644 index 0000000..aa379b8 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/context/helpers/TestRemover.java @@ -0,0 +1,65 @@ +package com.aventstack.extentreports.model.context.helpers; + +import java.util.List; +import java.util.stream.Collectors; + +import com.aventstack.extentreports.model.Test; + +public class TestRemover { + + /** + * Helper for removing test recursively. This flag determines when to break out + * of recursion + */ + private static boolean removed = false; + + private TestRemover() { + } + + /** + * Remove a test using its unique ID from a list + * + * @param list a list of {@link Test} + * @param test {@link Test} to be removed + */ + public static void remove(List testList, Test test) { + removed = false; + findAndRemoveTest(testList, test); + testList.forEach(Test::end); + } + + /** + * Recursively traverses all tests, nodes upto the last leaf to find and remove + * the specified test + * + * @param list a list of {@link Test} + * @param test {@link Test} to be removed + */ + private synchronized static void findAndRemoveTest(List list, Test test) { + List filteredTestList = list.stream().filter(x -> x.getId() == test.getId()).collect(Collectors.toList()); + + if (filteredTestList.size() == 1) { + removeTest(list, filteredTestList.get(0)); + removed = true; + return; + } + + for (Test t : list) { + if (removed) { + return; + } + findAndRemoveTest(t.getNodeContext().getAll(), test); + } + } + + /** + * Removes the test from a given list of tests + * + * @param list a list of {@link Test} + * @param test {@link Test} to be removed + */ + private static void removeTest(List list, Test test) { + list.remove(test); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/model/service/LogService.java b/src/main/java/com/aventstack/extentreports/model/service/LogService.java new file mode 100644 index 0000000..dfb7b2f --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/service/LogService.java @@ -0,0 +1,11 @@ +package com.aventstack.extentreports.model.service; + +import com.aventstack.extentreports.model.Log; + +public class LogService { + + public static Boolean logHasScreenCapture(Log log) { + return !log.getScreenCapture().isEmpty(); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/model/service/TestService.java b/src/main/java/com/aventstack/extentreports/model/service/TestService.java new file mode 100644 index 0000000..2b5d4a9 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/service/TestService.java @@ -0,0 +1,75 @@ +package com.aventstack.extentreports.model.service; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel; +import com.aventstack.extentreports.model.Test; + +public class TestService { + + public static Boolean testHasAttributes(Test test) { + return testHasAuthor(test) || testHasCategory(test) || testHasDevice(test); + } + + public static Boolean testHasAuthor(Test test) { + return !test.getAuthorContext().isEmpty(); + } + + public static Boolean testHasCategory(Test test) { + return !test.getCategoryContext().isEmpty(); + } + + public static Boolean testHasDevice(Test test) { + return !test.getDeviceContext().isEmpty(); + } + + public static Boolean testHasException(Test test) { + return !test.getExceptionInfoContext().isEmpty(); + } + + public static Boolean testHasChildren(Test test) { + return !test.getNodeContext().isEmpty(); + } + + public static Boolean testHasLog(Test test) { + return !test.getLogContext().isEmpty(); + } + + public static Boolean testHasScreenCapture(Test test) { + return !test.getScreenCaptureContext().isEmpty(); + } + + public static Boolean isTestBehaviorDriven(Test test) { + return test.getBddType() != null; + } + + public static String getBehaviorDrivenTypeName(Class bddType) + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, + InvocationTargetException { + Method method = bddType.getMethod("getGherkinName"); + Object o = method.invoke(null, (Object[]) null); + return o.toString(); + } + + public static String getBehaviorDrivenTypeName(Test test) throws NoSuchMethodException, SecurityException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException { + return getBehaviorDrivenTypeName(test.getBddType()); + } + + public static String getRunDuration(Test test) { + long diff = test.getEndTime().getTime() - test.getStartTime().getTime(); + long secs = diff / 1000; + long millis = diff % 1000; + long mins = secs / 60; + secs = secs % 60; + long hours = mins / 60; + mins = mins % 60; + return hours + "h " + mins + "m " + secs + "s+" + millis + "ms"; + } + + public static Long getRunDurationMillis(Test test) { + return test.getEndTime().getTime() - test.getStartTime().getTime(); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/resource/OfflineResxDelegate.java b/src/main/java/com/aventstack/extentreports/offline/OfflineResxDelegate.java similarity index 71% rename from src/main/java/com/aventstack/extentreports/resource/OfflineResxDelegate.java rename to src/main/java/com/aventstack/extentreports/offline/OfflineResxDelegate.java index 1cecae7..d4d043e 100644 --- a/src/main/java/com/aventstack/extentreports/resource/OfflineResxDelegate.java +++ b/src/main/java/com/aventstack/extentreports/offline/OfflineResxDelegate.java @@ -1,28 +1,28 @@ -package com.aventstack.extentreports.resource; +package com.aventstack.extentreports.offline; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; +import com.aventstack.extentreports.io.ResourceUtil; import com.aventstack.extentreports.utils.FileUtil; -import com.aventstack.extentreports.utils.ResourceUtil; public class OfflineResxDelegate { - + public static void saveOfflineResources(String baseResourceDirectory, String[] resx, String toPath) { FileUtil.createDirectory(toPath); for (String f : resx) { Path path = Paths.get(baseResourceDirectory, f); String fromPath = path.toString(); String toPathComplete = Paths.get(toPath, new File(f).getName()).toString(); - ResourceUtil.moveResource(fromPath, toPathComplete); - } + ResourceUtil.moveResource(fromPath, toPathComplete); + } } - + public static void saveOfflineResources(String[] resx, String toPath) { for (String f : resx) { - ResourceUtil.moveResource(f, toPath); - } + ResourceUtil.moveResource(f, toPath); + } } } diff --git a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java index cb0fbfc..1dedb56 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/AbstractReporter.java @@ -1,64 +1,189 @@ package com.aventstack.extentreports.reporter; +import java.io.IOException; import java.util.Calendar; +import java.util.Collection; import java.util.Date; +import java.util.List; import com.aventstack.extentreports.AnalysisStrategy; import com.aventstack.extentreports.ReportAggregates; +import com.aventstack.extentreports.ReportStatusStats; +import com.aventstack.extentreports.Status; +import com.aventstack.extentreports.mediastorage.LocalMediaStorageHandler; +import com.aventstack.extentreports.mediastorage.MediaStorage; +import com.aventstack.extentreports.model.Author; +import com.aventstack.extentreports.model.Category; +import com.aventstack.extentreports.model.Device; +import com.aventstack.extentreports.model.Log; +import com.aventstack.extentreports.model.ScreenCapture; +import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.ExceptionTestContextStore; +import com.aventstack.extentreports.model.context.SystemAttributeContext; +import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; -/** - * A base class for all Reporter types - * - */ -public abstract class AbstractReporter - extends ConfigurableReporter { +public abstract class AbstractReporter implements ExtentReporter { - protected Date startTime = Calendar.getInstance().getTime(); - protected Date endTime = startTime; - + private Date startTime = Calendar.getInstance().getTime(); + private Date endTime = startTime; private AnalysisStrategy strategy = AnalysisStrategy.TEST; + private MediaStorage media; + private List testList; + private List testRunnerLogs; + private ExceptionTestContextStore exceptionContext; + private TestAttributeTestContextStore categoryContext; + private TestAttributeTestContextStore authorContext; + private TestAttributeTestContextStore deviceContext; + private SystemAttributeContext systemAttributeContext; + private ReportStatusStats stats; + private Collection statusCollection; + public void flush(ReportAggregates reportAggregates) { - this.startTime = reportAggregates.getStartTime(); - this.endTime = reportAggregates.getEndTime(); + startTime = reportAggregates.getStartTime(); + endTime = reportAggregates.getEndTime(); + this.authorContext = reportAggregates.getAuthorContext(); + this.categoryContext = reportAggregates.getCategoryContext(); + this.deviceContext = reportAggregates.getDeviceContext(); + this.exceptionContext = reportAggregates.getExceptionContext(); + this.stats = reportAggregates.getReportStatusStats(); + this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); + this.testList = reportAggregates.getTestList(); + this.testRunnerLogs = reportAggregates.getTestRunnerLogs(); + this.statusCollection = reportAggregates.getStatusCollection(); } - - protected Date getStartTime() { + + public Date getStartTime() { return startTime; } - - protected void setEndTime(Date endTime) { + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public void setEndTime(Date endTime) { this.endTime = endTime; } - - protected Date getEndTime() { + + public Date getEndTime() { return endTime; } - - @Override - public void setAnalysisStrategy(AnalysisStrategy strategy){ - this.strategy = strategy; - } - - @Override - public AnalysisStrategy getAnalysisStrategy() { - return strategy; - } - - public long getRunDuration() { - return endTime.getTime() - startTime.getTime(); - } - - public String getLongRunDuration() { + + public void setAnalysisStrategy(AnalysisStrategy strategy) { + this.strategy = strategy; + } + + public AnalysisStrategy getAnalysisStrategy() { + return strategy; + } + + public long getRunDuration() { + return endTime.getTime() - startTime.getTime(); + } + + public String getLongRunDuration() { long millis = getRunDuration(); - - long secs = millis / 1000; - long ms = millis % 1000; - long mins = secs / 60; - secs = (secs % 60); - long hours = mins / 60; - mins = mins % 60; - - return hours + "h " + mins + "m " + secs + "s+" + ms + "ms"; - } + + long secs = millis / 1000; + long ms = millis % 1000; + long mins = secs / 60; + secs = (secs % 60); + long hours = mins / 60; + mins = mins % 60; + + return hours + "h " + mins + "m " + secs + "s+" + ms + "ms"; + } + + public List getTestList() { + return testList; + } + + public List getTestRunnerLogs() { + return testRunnerLogs; + } + + public TestAttributeTestContextStore getCategoryContextInfo() { + return categoryContext; + } + + public TestAttributeTestContextStore getAuthorContextInfo() { + return authorContext; + } + + public TestAttributeTestContextStore getDeviceContextInfo() { + return deviceContext; + } + + public ExceptionTestContextStore getExceptionContextInfo() { + return exceptionContext; + } + + public SystemAttributeContext getSystemAttributeContext() { + return systemAttributeContext; + } + + public ReportStatusStats getReportStatusStats() { + return stats; + } + + public Collection getStatusCollection() { + return statusCollection; + } + + @Override + public void onTestStarted(Test test) { + } + + @Override + public void onTestRemoved(Test test) { + } + + @Override + public void onNodeStarted(Test node) { + } + + @Override + public void onLogAdded(Test test, Log log) { + } + + @Override + public void onCategoryAssigned(Test test, Category category) { + } + + @Override + public void onAuthorAssigned(Test test, Author author) { + } + + @Override + public void onDeviceAssigned(Test test, Device device) { + } + + @Override + public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { + } + + @Override + public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { + } + + protected void autoCreateRelativePathMedia(ScreenCapture screenCapture, Boolean autoCreateRelativePath, + String destination) throws IOException { + // if user has not specific a configuration, exit + if (screenCapture.isBase64()) { + return; + } + // check always so user has the option to disable this setting at anytime + if (autoCreateRelativePath) { + if (media == null) { + media = new LocalMediaStorageHandler(); + media.init(destination); + } + media.storeMedia(screenCapture); + } + } + + @Override + public void stop() { + } + } diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index 67d30ef..aab016b 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -2,37 +2,22 @@ import java.io.File; import java.io.IOException; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; import java.util.HashMap; -import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import com.aventstack.extentreports.ExceptionTestContextImpl; import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.ReportAggregates; -import com.aventstack.extentreports.ReportStatusStats; import com.aventstack.extentreports.Status; -import com.aventstack.extentreports.SystemAttributeContext; -import com.aventstack.extentreports.TestAttributeTestContextProvider; -import com.aventstack.extentreports.mediastorage.LocalMediaStorageHandler; -import com.aventstack.extentreports.mediastorage.MediaStorage; -import com.aventstack.extentreports.model.Author; -import com.aventstack.extentreports.model.Category; -import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.Log; -import com.aventstack.extentreports.model.Media; import com.aventstack.extentreports.model.ScreenCapture; -import com.aventstack.extentreports.model.Screencast; import com.aventstack.extentreports.model.Test; -import com.aventstack.extentreports.reporter.configuration.BasicFileConfiguration; +import com.aventstack.extentreports.model.service.LogService; +import com.aventstack.extentreports.model.service.TestService; +import com.aventstack.extentreports.templating.FreemarkerTemplate; +import com.aventstack.extentreports.templating.TemplateConfig; import com.aventstack.extentreports.utils.FileUtil; -import com.aventstack.extentreports.utils.Writer; import com.aventstack.extentreports.viewdefs.Icon; import com.aventstack.extentreports.viewdefs.MaterialIcon; import com.aventstack.extentreports.viewdefs.TWBSColor; @@ -49,60 +34,22 @@ * A base class for all reporter types that generate an output file * */ -public abstract class BasicFileReporter extends AbstractReporter { +public abstract class BasicFileReporter extends ConfigurableReporter { private static final Logger logger = Logger.getLogger(BasicFileReporter.class.getName()); - private static final String DEFAULT_MEDIA_SAVE_PROPERTY_NAME = "autoCreateRelativePathMedia"; private static final String TEMPLATE_LOCATION = "view/"; private static String encoding = "UTF-8"; + private String filePath; + private String destination; + private Map templateModel; private String source; - protected String filePath; - protected String destination; - protected Map templateMap; - - private BasicFileConfiguration userConfig; - private MediaStorage media; - private List testList; - private List testRunnerLogs; - private ExceptionTestContextImpl exceptionContext; - private TestAttributeTestContextProvider categoryContext; - private TestAttributeTestContextProvider authorContext; - private TestAttributeTestContextProvider deviceContext; - private SystemAttributeContext systemAttributeContext; - private ReportStatusStats stats; - private Collection statusCollection; - - protected BasicFileReporter(String path) { - this.filePath = path; - } - - protected BasicFileReporter(File path) { - this.filePath = path.getAbsolutePath(); - } - - protected void setFilePath(String filePath) { - this.filePath = filePath; - } + private Configuration freemarkerConfig; - public String getFilePath() { - return filePath; - } - - public File getFileFile() { - return new File(filePath); - } - - protected void init(String[] configFilePath, BasicFileConfiguration userConfig) { - this.userConfig = userConfig; - - // Required to parse the start and end times in the HTML report. - Locale.setDefault(Locale.ENGLISH); - loadDefaultConfig(configFilePath); - - File f = new File(getFilePath()); + protected BasicFileReporter(File f) { + this.filePath = f.getAbsolutePath(); File parentFile; if (f.isDirectory() || FileUtil.getExtension(f).isEmpty()) { parentFile = f; @@ -115,40 +62,52 @@ protected void init(String[] configFilePath, BasicFileConfiguration userConfig) destinationFile.mkdirs(); } } + + protected BasicFileReporter(String path) { + this(new File(path)); + } - protected void loadUserConfig() { - for (Map.Entry entry : userConfig.getConfigMap().entrySet()) { - if (entry.getValue() != null) { - configContext.setConfig(entry.getKey().toString(), entry.getValue()); - } - } + protected void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFilePath() { + return filePath; } - private void loadDefaultConfig(String[] configFilePath) { - ClassLoader loader = getClass().getClassLoader(); - Arrays.stream(configFilePath).map(x -> loader.getResourceAsStream(x)).filter(x -> x != null).findFirst() - .ifPresent(x -> loadConfig(x)); + public File getFileFile() { + return new File(filePath); + } + + public String getDestinationPath() { + return destination; } @Override public void start() { - if (templateMap != null) { + if (templateModel != null) { return; } - templateMap = new HashMap<>(); - templateMap.put("report", this); - templateMap.put("MaterialIcon", new MaterialIcon()); - templateMap.put("Icon", new Icon()); - templateMap.put("TWBSColor", new TWBSColor()); + templateModel = new HashMap<>(); + templateModel.put("report", this); + templateModel.put("MaterialIcon", new MaterialIcon()); + templateModel.put("Icon", new Icon()); + templateModel.put("TWBSColor", new TWBSColor()); - BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_23); + BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_29); BeansWrapper beansWrapper = builder.build(); try { TemplateHashModel fieldTypeModel = (TemplateHashModel) beansWrapper.getEnumModels() .get(Status.class.getName()); - templateMap.put("Status", fieldTypeModel); + templateModel.put("Status", fieldTypeModel); + fieldTypeModel = (TemplateHashModel) beansWrapper.getStaticModels() + .get(TestService.class.getName()); + templateModel.put("TestService", fieldTypeModel); + fieldTypeModel = (TemplateHashModel) beansWrapper.getStaticModels() + .get(LogService.class.getName()); + templateModel.put("LogService", fieldTypeModel); } catch (TemplateModelException e) { logger.log(Level.SEVERE, "", e); } @@ -157,132 +116,26 @@ public void start() { @Override public synchronized void flush(ReportAggregates reportAggregates) { super.flush(reportAggregates); - this.authorContext = reportAggregates.getAuthorContext(); - this.categoryContext = reportAggregates.getCategoryContext(); - this.deviceContext = reportAggregates.getDeviceContext(); - this.exceptionContext = reportAggregates.getExceptionContext(); - this.stats = reportAggregates.getReportStatusStats(); - this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); - this.testList = reportAggregates.getTestList(); - this.testRunnerLogs = reportAggregates.getTestRunnerLogs(); - this.statusCollection = reportAggregates.getStatusCollection(); - } - - public List getTestList() { - return testList; - } - - public List getTestRunnerLogs() { - return testRunnerLogs; - } - - public TestAttributeTestContextProvider getCategoryContextInfo() { - return categoryContext; - } - - public TestAttributeTestContextProvider getAuthorContextInfo() { - return authorContext; - } - - public TestAttributeTestContextProvider getDeviceContextInfo() { - return deviceContext; - } - - public ExceptionTestContextImpl getExceptionContextInfo() { - return exceptionContext; - } - - public SystemAttributeContext getSystemAttributeContext() { - return systemAttributeContext; - } - - public ReportStatusStats getReportStatusStats() { - return stats; - } - - public Collection getStatusCollection() { - return statusCollection; - } - - @Override - public void onTestStarted(Test test) { - } - - @Override - public void onTestRemoved(Test test) { - } - - @Override - public void onNodeStarted(Test node) { - } - - @Override - public void onLogAdded(Test test, Log log) { - } - - @Override - public void onCategoryAssigned(Test test, Category category) { - } - - @Override - public void onAuthorAssigned(Test test, Author author) { - } - - @Override - public void onDeviceAssigned(Test test, Device device) { } @Override public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { - mediaExists(screenCapture); - autoCreateRelativePathMedia(screenCapture); + onScreenCaptureAdded(screenCapture); } @Override public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { - mediaExists(screenCapture); - autoCreateRelativePathMedia(screenCapture); - } - - private void mediaExists(Media m) { - if (m.getPath() != null && !new File(m.getPath()).exists()) { - } + onScreenCaptureAdded(screenCapture); } - private void autoCreateRelativePathMedia(ScreenCapture screenCapture) throws IOException { - // if user has not specific a configuration, exit - if (userConfig == null || screenCapture.isBase64()) - return; - - String autoCreateRelativePathMedia = userConfig.getConfigMap().get(DEFAULT_MEDIA_SAVE_PROPERTY_NAME); - // check always so user has the option to disable this setting at anytime + private void onScreenCaptureAdded(ScreenCapture screenCapture) throws IOException { + String autoCreateRelativePathMedia = (String) getConfigurationStore() + .getConfig(DEFAULT_MEDIA_SAVE_PROPERTY_NAME); if (autoCreateRelativePathMedia != null && Boolean.valueOf(autoCreateRelativePathMedia)) { - if (media == null) { - media = new LocalMediaStorageHandler(); - media.init(destination); - } - media.storeMedia(screenCapture); + autoCreateRelativePathMedia(screenCapture, Boolean.valueOf(autoCreateRelativePathMedia), destination); } } - @Override - public void stop() { - } - - @Override - public Date getStartTime() { - return super.getStartTime(); - } - - @Override - public Date getEndTime() { - return super.getEndTime(); - } - - @Override - public void onScreencastAdded(Test test, Screencast screencast) throws IOException { - } - public boolean containsStatus(String status) { Status s = Status.valueOf(status.toUpperCase()); return containsStatus(s); @@ -293,11 +146,8 @@ public boolean containsStatus(Status status) { } protected void processTemplate(Template template, File outputFile) throws TemplateException, IOException { - StringWriter out = new StringWriter(); - template.process(templateMap, out); - source = out.toString(); - Writer.getInstance().write(outputFile, source); - out.close(); + FreemarkerTemplate freemarkerTemplate = new FreemarkerTemplate(getFreemarkerConfig()); + freemarkerTemplate.writeTemplate(template, templateModel, outputFile); } protected String getSource() { @@ -305,20 +155,22 @@ protected String getSource() { } protected Configuration getFreemarkerConfig() { - Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); - cfg.setClassForTemplateLoading(ExtentReports.class, TEMPLATE_LOCATION); - cfg.setDefaultEncoding(encoding); - return cfg; + if (freemarkerConfig == null) { + TemplateConfig freemarkerConfig = new TemplateConfig(); + this.freemarkerConfig = freemarkerConfig.getFreemarkerConfig(ExtentReports.class, TEMPLATE_LOCATION, + encoding); + } + return freemarkerConfig; } protected Boolean enforceOfflineMode() { - if (configContext.containsKey("enableOfflineMode")) { - String offlineMode = String.valueOf(configContext.getValue("enableOfflineMode")); - if (!configContext.containsKey("offlineDirectory") && offlineMode.equals("true")) { + if (getConfigurationStore().containsConfig("enableOfflineMode")) { + String offlineMode = String.valueOf(getConfigurationStore().containsConfig("enableOfflineMode")); + if (!getConfigurationStore().containsConfig("offlineDirectory") && offlineMode.equals("true")) { return true; } } return false; } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java index 11ad6b7..6c4e5e7 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java @@ -5,29 +5,22 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; +import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; -import com.aventstack.extentreports.ExtentReporter; -import com.aventstack.extentreports.externalconfig.ConfigLoader; -import com.aventstack.extentreports.externalconfig.model.ConfigMap; +import com.aventstack.extentreports.configuration.ConfigurationBuilder; +import com.aventstack.extentreports.configuration.ConfigurationStore; +import com.aventstack.extentreports.reporter.configuration.BasicConfiguration; -/** - * A base class to provide bootstrapping for loading custom configuration for - * the Reporter using XML or Properties file - * - */ -public abstract class ConfigurableReporter implements ExtentReporter { +public abstract class ConfigurableReporter extends AbstractReporter { private static final Logger logger = Logger.getLogger(ConfigurableReporter.class.getName()); - - /** - * A key-value pair holding information from default and the user-provided - * configuration - */ - protected ConfigMap configContext = new ConfigMap(); - + + private BasicConfiguration basicConfiguration; + /** * Loads configuration from an XML file * @@ -55,9 +48,9 @@ public void loadXMLConfig(String filePath) { * @param silent If silent, no errors will be thrown */ public void loadXMLConfig(File file, Boolean silent) { - ConfigLoader configLoader = new ConfigLoader(file, silent); - ConfigMap config = configLoader.getConfigurationHash(); - configContext.appendConfig(config); + ConfigurationBuilder builder = new ConfigurationBuilder(file, silent); + ConfigurationStore store = builder.getConfigurationStore(); + basicConfiguration.getConfigurationStore().extendConfig(store); } /** @@ -68,7 +61,7 @@ public void loadXMLConfig(File file, Boolean silent) { public void loadConfig(Properties properties) { properties.entrySet().forEach(o -> { if (o.getKey() != null) { - configContext.setConfig(o.getKey().toString(), o.getValue()); + basicConfiguration.getConfigurationStore().storeConfig(o.getKey().toString(), o.getValue()); } }); } @@ -105,14 +98,32 @@ public void loadConfig(String filePath) { logger.log(Level.SEVERE, "Default Properties file not found", e); } } + + protected void loadUserConfig() { + for (Map.Entry entry : getConfigurationStore().getStore().entrySet()) { + getConfigurationStore().storeConfig(entry.getKey(), entry.getValue()); + } + } + + protected void init(String[] configFilePath, BasicConfiguration userConfig) { + basicConfiguration = userConfig; + loadInternalReporterConfiguration(configFilePath); + } + + protected void loadInternalReporterConfiguration(String[] configFilePath) { + ClassLoader loader = getClass().getClassLoader(); + Arrays.stream(configFilePath).map(x -> loader.getResourceAsStream(x)).filter(x -> x != null).findFirst() + .ifPresent(x -> loadConfig(x)); + } /** * Returns the current configuration (default and user-defined) * - * @return a {@link ConfigMap} containing key-value pairs of config entries + * @return a {@link ConfigurationStore} containing key-value pairs of config + * entries */ - public ConfigMap getConfigContext() { - return configContext; + public ConfigurationStore getConfigurationStore() { + return basicConfiguration.getConfigurationStore(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/impl/ConsoleLogger.java b/src/main/java/com/aventstack/extentreports/reporter/ConsoleLogger.java similarity index 90% rename from src/main/java/com/aventstack/extentreports/reporter/impl/ConsoleLogger.java rename to src/main/java/com/aventstack/extentreports/reporter/ConsoleLogger.java index 950cba5..72f954f 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/impl/ConsoleLogger.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ConsoleLogger.java @@ -1,4 +1,4 @@ -package com.aventstack.extentreports.reporter.impl; +package com.aventstack.extentreports.reporter; import java.io.IOException; import java.util.logging.Level; @@ -9,9 +9,7 @@ import com.aventstack.extentreports.model.Device; import com.aventstack.extentreports.model.Log; import com.aventstack.extentreports.model.ScreenCapture; -import com.aventstack.extentreports.model.Screencast; import com.aventstack.extentreports.model.Test; -import com.aventstack.extentreports.reporter.AbstractReporter; public class ConsoleLogger extends AbstractReporter { @@ -71,9 +69,6 @@ public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) { LOGGER.log(Level.INFO, "A new screencapture for log " + log.getDetails() + " created"); } - @Override - public void onScreencastAdded(Test test, Screencast screencast) { } - @Override public String getReporterName() { return REPORTER_NAME; diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java deleted file mode 100644 index cfa4b39..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aventstack.extentreports.reporter; - -import java.io.File; - -import com.aventstack.extentreports.ReportAggregates; - -/** - * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options - * via the config() method. - */ -public class ExtentAventReporter - extends BasicFileReporter { - - private static final String REPORTER_NAME = "avent"; - - public ExtentAventReporter(String path) { - super(path); - } - - public ExtentAventReporter(File file) { - super(file); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java deleted file mode 100644 index 0a609b7..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aventstack.extentreports.reporter; - -import java.io.File; - -import com.aventstack.extentreports.ReportAggregates; - -/** - * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options - * via the config() method. - */ -public class ExtentBDDReporter - extends BasicFileReporter { - - private static final String REPORTER_NAME = "bdd"; - - public ExtentBDDReporter(String path) { - super(path); - } - - public ExtentBDDReporter(File file) { - super(file); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java deleted file mode 100644 index a3dbee1..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aventstack.extentreports.reporter; - -import java.io.File; - -import com.aventstack.extentreports.ReportAggregates; - -/** - * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options - * via the config() method. - */ -public class ExtentCardsReporter - extends BasicFileReporter { - - private static final String REPORTER_NAME = "cards"; - - public ExtentCardsReporter(String path) { - super(path); - } - - public ExtentCardsReporter(File file) { - super(file); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java deleted file mode 100644 index c36489a..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.aventstack.extentreports.reporter; - -import java.io.File; - -import com.aventstack.extentreports.ReportAggregates; -import com.aventstack.extentreports.SourceProvider; - -/** - * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options - * via the config() method. - */ -public class ExtentEmailReporter - extends BasicFileReporter - implements SourceProvider { - - private static final String REPORTER_NAME = "email"; - - public ExtentEmailReporter(String path) { - super(path); - } - - public ExtentEmailReporter(File file) { - super(file); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - - @Override - public String getSource() { - return super.getSource(); - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java index 788c4dd..11c7d40 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java @@ -10,59 +10,58 @@ import freemarker.template.Template; import freemarker.template.TemplateException; - + /** - * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several - * configuration options via the config() method. + * The ExtentSparkReporter creates a rich standalone spark file. It allows + * several configuration options via the config() method. */ public class ExtentHtmlReporter extends BasicFileReporter { - private static final Logger logger = Logger.getLogger(ExtentHtmlReporter.class.getName()); - private static final String REPORTER_NAME = "v3html"; + private static final Logger logger = Logger.getLogger(ExtentHtmlReporter.class.getName()); + private static final String REPORTER_NAME = "html"; private static final String TEMPLATE_NAME = "v3html/v3-html-index.ftl"; private static final String[] DEFAULT_CONFIG_FILE_PATH = new String[] { "html.properties", "src/main/resources/html.properties" }; - private ExtentHtmlReporterConfiguration userConfig = new ExtentHtmlReporterConfiguration(this); - - public ExtentHtmlReporter(String path) { - super(path); - init(DEFAULT_CONFIG_FILE_PATH, config()); - } + private ExtentHtmlReporterConfiguration externalUserConfiguration = new ExtentHtmlReporterConfiguration(this); - public ExtentHtmlReporter(File file) { - super(file); - init(DEFAULT_CONFIG_FILE_PATH, config()); - } + public ExtentHtmlReporter(String path) { + super(path); + init(DEFAULT_CONFIG_FILE_PATH, config()); + } - public ExtentHtmlReporterConfiguration config() { - return userConfig; - } + public ExtentHtmlReporter(File file) { + super(file); + init(DEFAULT_CONFIG_FILE_PATH, config()); + } - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - super.flush(reportAggregates); + public ExtentHtmlReporterConfiguration config() { + return externalUserConfiguration; + } - if (getTestList().isEmpty()) - return; + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + super.flush(reportAggregates); + if (getTestList().isEmpty()) { + return; + } + if (enforceOfflineMode()) { + externalUserConfiguration.enableOfflineMode(true); + } - if (enforceOfflineMode()) { - userConfig.enableOfflineMode(true); - } - - loadUserConfig(); + loadUserConfig(); - try { - Template template = getFreemarkerConfig().getTemplate(TEMPLATE_NAME); - processTemplate(template, new File(filePath)); - } catch (IOException | TemplateException e) { - logger.log(Level.SEVERE, "An exception occurred", e); - } - } + try { + Template template = getFreemarkerConfig().getTemplate(TEMPLATE_NAME); + processTemplate(template, new File(getFilePath())); + } catch (IOException | TemplateException e) { + logger.log(Level.SEVERE, "An exception occurred", e); + } + } - @Override - public String getReporterName() { - return REPORTER_NAME; - } + @Override + public String getReporterName() { + return REPORTER_NAME; + } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java deleted file mode 100644 index 5ec6f70..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ /dev/null @@ -1,682 +0,0 @@ -package com.aventstack.extentreports.reporter; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import org.bson.Document; -import org.bson.types.ObjectId; - -import com.aventstack.extentreports.ReportAggregates; -import com.aventstack.extentreports.ReportStatusStats; -import com.aventstack.extentreports.Status; -import com.aventstack.extentreports.SystemAttributeContext; -import com.aventstack.extentreports.TestAttributeTestContextProvider; -import com.aventstack.extentreports.mediastorage.KlovMediaStorageHandler; -import com.aventstack.extentreports.mediastorage.model.KlovMedia; -import com.aventstack.extentreports.model.Author; -import com.aventstack.extentreports.model.BasicMongoReportElement; -import com.aventstack.extentreports.model.Category; -import com.aventstack.extentreports.model.Device; -import com.aventstack.extentreports.model.ExceptionInfo; -import com.aventstack.extentreports.model.Log; -import com.aventstack.extentreports.model.ScreenCapture; -import com.aventstack.extentreports.model.Screencast; -import com.aventstack.extentreports.model.SystemAttribute; -import com.aventstack.extentreports.model.Test; -import com.aventstack.extentreports.model.TestAttribute; -import com.aventstack.extentreports.utils.IntUtils; -import com.aventstack.extentreports.utils.MongoUtil; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientOptions; -import com.mongodb.MongoClientURI; -import com.mongodb.MongoCredential; -import com.mongodb.ServerAddress; -import com.mongodb.client.FindIterable; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; - -/** - * ExtentKlovReporter is a NoSQL database reporter (MongoDB), which updates - * information in the database which is then used by the ExtentX server to - * display in-depth analysis. - */ -public class ExtentKlovReporter extends AbstractReporter { - - private static final String DEFAULT_PROJECT_NAME_PROP = "klov.project.name"; - private static final String DEFAULT_REPORT_NAME_PROP = "klov.report.name"; - private static final String DEFAULT_MONGODB_HOST_PROP = "mongodb.host"; - private static final String DEFAULT_MONGODB_PORT_PROP = "mongodb.port"; - private static final String DEFAULT_MONGODB_URI_PROP = "mongodb.uri"; - private static final String DEFAULT_KLOV_HOST_PROP = "klov.host"; - private static final String DEFAULT_KLOV_PORT_PROP = "klov.port"; - private static final String REPORTER_NAME = "klov"; - private static final String DB_NAME = "klov"; - private static final String DEFAULT_PROJECT_NAME = "Default"; - - private String url; - - private List testList; - private ReportStatusStats stats; - private SystemAttributeContext systemAttributeContext; - private TestAttributeTestContextProvider categoryContext; - private TestAttributeTestContextProvider authorContext; - private TestAttributeTestContextProvider deviceContext; - private Map categoryNameObjectIdCollection = new HashMap<>(); - private Map authorNameObjectIdCollection = new HashMap<>(); - private Map deviceNameObjectIdCollection = new HashMap<>(); - private Map exceptionNameObjectIdCollection = new HashMap<>(); - - private ObjectId reportId; - private String reportName; - private ObjectId projectId; - private String projectName; - - private MongoClient mongoClient; - - private MongoCollection projectCollection; - private MongoCollection reportCollection; - private MongoCollection testCollection; - private MongoCollection logCollection; - private MongoCollection exceptionCollection; - private MongoCollection mediaCollection; - private MongoCollection categoryCollection; - private MongoCollection authorCollection; - private MongoCollection deviceCollection; - private MongoCollection environmentCollection; - - static { - /* use mongodb reporting for only critical/severe events */ - Logger mongoLogger = Logger.getLogger("org.mongodb.driver"); - mongoLogger.setLevel(Level.SEVERE); - } - - /** - * Initializes the KlovReporter - */ - public ExtentKlovReporter() { - } - - /** - * Initializes the KlovReporter with project and report names - * - * @param projectName Name of the project - * @param reportName Name of the report - */ - public ExtentKlovReporter(String projectName, String reportName) { - this.projectName = projectName; - this.reportName = reportName; - } - - /** - * Sets the project name - * - * @param projectName Name of the project - */ - public void setProjectName(String projectName) { - this.projectName = projectName; - } - - /** - * Sets the report name - * - * @param reportName Name of the report - */ - public void setReportName(String reportName) { - this.reportName = reportName; - } - - /** - * Initialize Mongo DB connection with host and default port: 27017 - * - * @param host host name - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(String host) { - mongoClient = new MongoClient(host, 27017); - return this; - } - - /** - * Initialize Mongo DB connection with host and {@link MongoClientOptions} - * - * @param host host name - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(String host, MongoClientOptions options) { - mongoClient = new MongoClient(host, options); - return this; - } - - /** - * Initialize Mongo DB connection with host and post - * - * @param host host name - * @param port port number - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(String host, int port) { - mongoClient = new MongoClient(host, port); - return this; - } - - /** - * Initialize Mongo DB connection with a {@link MongoClientURI} - * - * @param uri {@link MongoClientURI} uri - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(MongoClientURI uri) { - mongoClient = new MongoClient(uri); - return this; - } - - /** - * Initializes the Mongo DB connection with {@link ServerAddress} - * - * @param addr {@link ServerAddress} server address - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr) { - mongoClient = new MongoClient(addr); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} - * addresses - * - * @param seeds A list of {@link ServerAddress} server addresses - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds) { - mongoClient = new MongoClient(seeds); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} and - * {@link MongoCredential} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList) { - mongoClient = new MongoClient(seeds, credentialsList); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress}, - * {@link MongoCredential} and {@link MongoClientOptions} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList, - MongoClientOptions options) { - mongoClient = new MongoClient(seeds, credentialsList, options); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} and - * {@link MongoClientOptions} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, MongoClientOptions options) { - mongoClient = new MongoClient(seeds, options); - return this; - } - - /** - * Initializes the Mongo DB connection with {@link ServerAddress} and a list of - * {@link MongoCredential} credentials - * - * @param addr {@link ServerAddress} server address - * @param credentialsList A list of {@link MongoCredential} credentials - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList) { - mongoClient = new MongoClient(addr, credentialsList); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress}, - * {@link MongoCredential} and {@link MongoClientOptions} - * - * @param addr A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList, - MongoClientOptions options) { - mongoClient = new MongoClient(addr, credentialsList, options); - return this; - } - - /** - * Initializes the Mongo DB connection with a {@link ServerAddress} and - * {@link MongoClientOptions} - * - * @param addr A list of {@link ServerAddress} server addresses - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, MongoClientOptions options) { - mongoClient = new MongoClient(addr, options); - return this; - } - - /** - * Initializes the Mongo DB connection with a connection url - * - * @param url Url string - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initKlovServerConnection(String url) { - this.url = url; - return this; - } - - public void loadInitializationParams(String propertiesPath) throws FileNotFoundException { - File f = new File(propertiesPath); - InputStream stream = new FileInputStream(f); - loadConfig(stream); - loadInitializationParams(); - } - - public void loadInitializationParams(Properties props) { - loadConfig(props); - loadInitializationParams(); - } - - private void loadInitializationParams() { - - String mongoUri = getConfigValue(DEFAULT_MONGODB_URI_PROP); - if (mongoUri == null || mongoUri.isEmpty()) { - String mongoHost = getConfigValue(DEFAULT_MONGODB_HOST_PROP); - String mongoPort = getConfigValue(DEFAULT_MONGODB_PORT_PROP); - int mongoPortInt = IntUtils.tryParseInt(mongoPort) == true ? Integer.valueOf(mongoPort) : -1; - if (mongoHost != null && mongoPortInt != -1) { - initMongoDbConnection(mongoHost, mongoPortInt); - } else if (mongoHost != null) { - initMongoDbConnection(mongoHost); - } - } else { - initMongoDbConnection(new MongoClientURI(mongoUri)); - } - - String projectName = System.getProperty(DEFAULT_PROJECT_NAME_PROP); - projectName = projectName == null || projectName.isEmpty() ? getConfigValue(DEFAULT_PROJECT_NAME_PROP) - : projectName; - this.projectName = projectName == null || projectName.isEmpty() ? this.projectName : projectName; - - String reportName = System.getProperty(DEFAULT_REPORT_NAME_PROP); - reportName = reportName == null || reportName.isEmpty() ? getConfigValue(DEFAULT_REPORT_NAME_PROP) : reportName; - this.reportName = reportName == null || reportName.isEmpty() ? this.reportName : reportName; - - String klovHost = getConfigValue(DEFAULT_KLOV_HOST_PROP); - String klovPort = getConfigValue(DEFAULT_KLOV_PORT_PROP); - - if (klovHost != null && klovPort != null) { - String uri = klovHost + ":" + klovPort; - initKlovServerConnection(uri); - } else if (klovHost != null) { - initKlovServerConnection(klovHost); - } else { - } - } - - private String getConfigValue(String key) { - return String.valueOf(configContext.getValue(key)); - } - - @Override - public void start() { - MongoDatabase db = mongoClient.getDatabase(DB_NAME); - initCollections(db); - setupProject(); - } - - private void initCollections(MongoDatabase db) { - projectCollection = db.getCollection("project"); - reportCollection = db.getCollection("report"); - testCollection = db.getCollection("test"); - logCollection = db.getCollection("log"); - exceptionCollection = db.getCollection("exception"); - mediaCollection = db.getCollection("media"); - categoryCollection = db.getCollection("category"); - authorCollection = db.getCollection("author"); - deviceCollection = db.getCollection("device"); - environmentCollection = db.getCollection("environment"); - } - - private void setupProject() { - String projectName = this.projectName == null || this.projectName.isEmpty() ? DEFAULT_PROJECT_NAME - : this.projectName; - - Document doc = new Document("name", projectName); - Document project = projectCollection.find(doc).first(); - - if (project != null) { - projectId = project.getObjectId("_id"); - } else { - doc.append("createdAt", Calendar.getInstance().getTime()); - projectCollection.insertOne(doc); - projectId = MongoUtil.getId(doc); - } - - setupReport(projectName); - } - - private void setupReport(String projectName) { - String reportName = this.reportName == null || this.reportName.isEmpty() - ? "Build " + Calendar.getInstance().getTimeInMillis() - : this.reportName; - - Document doc = new Document("name", reportName).append("startTime", getStartTime()).append("project", projectId) - .append("projectName", projectName); - - reportCollection.insertOne(doc); - reportId = MongoUtil.getId(doc); - } - - @Override - public void stop() { - mongoClient.close(); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - setEndTime(Calendar.getInstance().getTime()); - this.testList = reportAggregates.getTestList(); - - if (testList == null || testList.isEmpty()) { - return; - } - - this.authorContext = reportAggregates.getAuthorContext(); - this.categoryContext = reportAggregates.getCategoryContext(); - this.deviceContext = reportAggregates.getDeviceContext(); - this.stats = reportAggregates.getReportStatusStats(); - this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); - - Status buildStatus = reportAggregates.getStatus(); - - Document doc = new Document("endTime", getEndTime()).append("duration", getRunDuration()) - .append("status", String.valueOf(buildStatus)).append("parentLength", stats.getParentCount()) - .append("passParentLength", stats.getParentCountPass()) - .append("failParentLength", stats.getParentCountFail()) - .append("fatalParentLength", stats.getParentCountFatal()) - .append("errorParentLength", stats.getParentCountError()) - .append("warningParentLength", stats.getParentCountWarning()) - .append("skipParentLength", stats.getParentCountSkip()) - .append("exceptionsParentLength", stats.getParentCountExceptions()) - .append("childLength", stats.getChildCount()).append("passChildLength", stats.getChildCountPass()) - .append("failChildLength", stats.getChildCountFail()) - .append("fatalChildLength", stats.getChildCountFatal()) - .append("errorChildLength", stats.getChildCountError()) - .append("warningChildLength", stats.getChildCountWarning()) - .append("skipChildLength", stats.getChildCountSkip()) - .append("infoChildLength", stats.getChildCountInfo()) - .append("exceptionsChildLength", stats.getChildCountExceptions()) - .append("grandChildLength", stats.getGrandChildCount()) - .append("passGrandChildLength", stats.getGrandChildCountPass()) - .append("failGrandChildLength", stats.getGrandChildCountFail()) - .append("fatalGrandChildLength", stats.getGrandChildCountFatal()) - .append("errorGrandChildLength", stats.getGrandChildCountError()) - .append("warningGrandChildLength", stats.getGrandChildCountWarning()) - .append("skipGrandChildLength", stats.getGrandChildCountSkip()) - .append("exceptionsGrandChildLength", stats.getGrandChildCountExceptions()) - .append("analysisStrategy", String.valueOf(getAnalysisStrategy())); - - reportCollection.updateOne(new Document("_id", reportId), new Document("$set", doc)); - - insertUpdateSystemAttribute(); - } - - public List getCollectionValues(Map collection) { - if (collection == null || collection.isEmpty()) - return null; - return collection.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList()); - } - - private void insertUpdateSystemAttribute() { - List systemAttrList = systemAttributeContext.getSystemAttributeList(); - Document doc; - - for (SystemAttribute attr : systemAttrList) { - doc = new Document("project", projectId).append("report", reportId).append("name", attr.getName()); - - Document envSingle = environmentCollection.find(doc).first(); - - if (envSingle == null) { - doc.append("value", attr.getValue()); - environmentCollection.insertOne(doc); - } else { - ObjectId id = envSingle.getObjectId("_id"); - doc = new Document("_id", id).append("value", attr.getValue()); - environmentCollection.updateOne(new Document("_id", id), new Document("$set", doc)); - } - } - } - - @Override - public void onTestStarted(Test test) { - onTestStartedHelper(test); - } - - @Override - public synchronized void onNodeStarted(Test node) { - onTestStartedHelper(node); - } - - private void onTestStartedHelper(Test test) { - Document doc = new Document("project", projectId).append("report", reportId).append("reportName", reportName) - .append("level", test.getLevel()).append("name", test.getName()) - .append("status", test.getStatus().toString()).append("description", test.getDescription()) - .append("startTime", test.getStartTime()).append("endTime", test.getEndTime()) - .append("bdd", test.isBehaviorDrivenType()).append("leaf", test.getChildrenNodes().size() == 0) - .append("childNodesLength", test.getChildrenNodes().size()); - - if (test.isBehaviorDrivenType()) { - doc.append("bddType", test.getBehaviorDrivenType().getSimpleName()); - } - - if (test.getParent() != null) { - doc.append("parent", test.getParent().getObjectId()).append("parentName", test.getParent().getName()); - updateTestChildrenCount(test.getParent()); - updateTestDesc(test.getParent()); - } - - testCollection.insertOne(doc); - ObjectId testId = MongoUtil.getId(doc); - test.setObjectId(testId); - } - - private void updateTestDesc(Test test) { - Document doc = new Document("description", test.getDescription()); - testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); - } - - private void updateTestChildrenCount(Test test) { - Document doc = new Document("childNodesLength", test.getChildrenNodes().size()); - testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); - } - - @Override - public synchronized void onLogAdded(Test test, Log log) { - Document doc = new Document("test", test.getObjectId()).append("project", projectId).append("report", reportId) - .append("testName", test.getName()).append("sequence", log.getSequence()) - .append("status", log.getStatus().toString()).append("timestamp", log.getTimestamp()) - .append("details", log.getDetails()); - - if (log.getExceptionInfo() != null) { - doc.append("exception", log.getExceptionInfo().getExceptionName()).append("stacktrace", - log.getExceptionInfo().getStackTrace()); - } - - if (log.hasScreenCapture() && log.getScreenCaptureContext().getFirst().isBase64()) { - doc.append("details", log.getDetails() + log.getScreenCaptureContext().getFirst().getSource()); - } - - logCollection.insertOne(doc); - - ObjectId logId = MongoUtil.getId(doc); - log.setObjectId(logId); - - // check for exceptions.. - if (test.hasException()) { - if (exceptionNameObjectIdCollection == null) - exceptionNameObjectIdCollection = new HashMap<>(); - - ExceptionInfo ex = test.getExceptionInfoList().get(0); - - ObjectId exceptionId; - doc = new Document("report", reportId).append("project", projectId).append("name", ex.getExceptionName()); - - FindIterable iterable = exceptionCollection.find(doc); - Document docException = iterable.first(); - - // check if a matching exception name is available in 'Exception' collection - // (MongoDB) - // if a matching exception name is found, associate with this exception's - // ObjectId - if (!exceptionNameObjectIdCollection.containsKey(ex.getExceptionName())) { - if (docException != null) { - exceptionNameObjectIdCollection.put(ex.getExceptionName(), docException.getObjectId("_id")); - } else { - doc = new Document("project", projectId).append("report", reportId) - .append("name", ex.getExceptionName()).append("stacktrace", ex.getStackTrace()) - .append("testCount", 0); - - exceptionCollection.insertOne(doc); - - exceptionId = MongoUtil.getId(doc); - docException = exceptionCollection.find(new Document("_id", exceptionId)).first(); - - exceptionNameObjectIdCollection.put(ex.getExceptionName(), exceptionId); - } - } - - Integer testCount = ((Integer) (docException.get("testCount"))) + 1; - doc = new Document("testCount", testCount); - - exceptionCollection.updateOne(new Document("_id", docException.getObjectId("_id")), - new Document("$set", doc)); - - doc = new Document("exception", exceptionNameObjectIdCollection.get(ex.getExceptionName())); - - testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); - updateTestDesc(test); - } - - endTestRecursive(test); - } - - private void endTestRecursive(Test test) { - Document doc = new Document("status", test.getStatus().toString()).append("endTime", test.getEndTime()) - .append("duration", test.getRunDurationMillis()).append("leaf", test.getChildrenNodes().size() == 0) - .append("childNodesLength", test.getChildrenNodes().size()).append("categorized", test.hasCategory()) - .append("description", test.getDescription()); - - testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); - - if (test.getLevel() > 0) { - endTestRecursive(test.getParent()); - } - } - - public void assignAttribute(Test test, TestAttribute attribute, - Map nameObjectIdCollection, MongoCollection mongoCollection, - TestAttributeTestContextProvider attributeContext) { - } - - @Override - public void onCategoryAssigned(Test test, Category category) { - assignAttribute(test, category, categoryNameObjectIdCollection, categoryCollection, categoryContext); - } - - @Override - public void onAuthorAssigned(Test test, Author author) { - assignAttribute(test, author, authorNameObjectIdCollection, authorCollection, authorContext); - } - - private KlovMediaStorageHandler mediaStorageHandler; - - @Override - public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { - saveScreenCapture(test, screenCapture); - } - - @Override - public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { - screenCapture.setLogObjectId(log.getObjectId()); - saveScreenCapture(log, screenCapture); - } - - private void saveScreenCapture(BasicMongoReportElement el, ScreenCapture screenCapture) throws IOException { - if (mediaStorageHandler == null) { - KlovMedia klovMedia = new KlovMedia(projectId, reportId, mediaCollection); - mediaStorageHandler = new KlovMediaStorageHandler(url, klovMedia); - } - mediaStorageHandler.saveScreenCapture(el, screenCapture); - } - - @Override - public void onScreencastAdded(Test test, Screencast screencast) throws IOException { - } - - /** - * Returns the active Project ID - * - * @return A {@link ObjectId} object - */ - public ObjectId getProjectId() { - return projectId; - } - - /** - * Returns the active Report ID - * - * @return A {@link ObjectId} object - */ - public ObjectId getReportId() { - return reportId; - } - - @Override - public void onTestRemoved(Test test) { - } - - @Override - public void onDeviceAssigned(Test test, Device device) { - assignAttribute(test, device, deviceNameObjectIdCollection, deviceCollection, deviceContext); - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java index 681b59a..27accad 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java @@ -6,7 +6,7 @@ import java.util.logging.Logger; import com.aventstack.extentreports.ReportAggregates; -import com.aventstack.extentreports.reporter.configuration.ExtentLoggerFormatterConfiguration; +import com.aventstack.extentreports.reporter.configuration.ExtentLoggerReporterConfiguration; import freemarker.template.Template; import freemarker.template.TemplateException; @@ -26,7 +26,7 @@ public class ExtentLoggerReporter extends BasicFileReporter { private static final String[] DEFAULT_CONFIG_FILE_PATH = new String[] { "logger.properties", "src/main/resources/logger.properties" }; - private ExtentLoggerFormatterConfiguration userConfig = new ExtentLoggerFormatterConfiguration(this); + private ExtentLoggerReporterConfiguration userConfig = new ExtentLoggerReporterConfiguration(this); public ExtentLoggerReporter(String path) { super(path); @@ -38,7 +38,7 @@ public ExtentLoggerReporter(File file) { init(DEFAULT_CONFIG_FILE_PATH, config()); } - public ExtentLoggerFormatterConfiguration config() { + public ExtentLoggerReporterConfiguration config() { return userConfig; } @@ -56,18 +56,18 @@ public synchronized void flush(ReportAggregates reportAggregates) { try { Template template = getFreemarkerConfig().getTemplate(TEMPLATE_NAME); - processTemplate(template, new File(destination + "index.html")); - if (String.valueOf(configContext.getValue("enableDashboard")).equalsIgnoreCase("true")) { + processTemplate(template, new File(getDestinationPath() + "index.html")); + if (String.valueOf(getConfigurationStore().getConfig("enableDashboard")).equalsIgnoreCase("true")) { template = getFreemarkerConfig().getTemplate(DASHBOARD_TEMPLATE_NAME); - processTemplate(template, new File(destination + "dashboard.html")); + processTemplate(template, new File(getDestinationPath() + "dashboard.html")); } - if (!getCategoryContextInfo().getTestAttributeTestContextList().isEmpty()) { + if (!getCategoryContextInfo().getTestAttributeTestContext().isEmpty()) { template = getFreemarkerConfig().getTemplate(CATEGORY_TEMPLATE_NAME); - processTemplate(template, new File(destination + "tag.html")); + processTemplate(template, new File(getDestinationPath() + "tag.html")); } - if (!getExceptionContextInfo().getExceptionTestContextList().isEmpty()) { + if (!getExceptionContextInfo().getExceptionTestContext().isEmpty()) { template = getFreemarkerConfig().getTemplate(EXCEPTION_TEMPLATE_NAME); - processTemplate(template, new File(destination + "exception.html")); + processTemplate(template, new File(getDestinationPath() + "exception.html")); } } catch (IOException | TemplateException e) { logger.log(Level.SEVERE, "An exception occurred", e); diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentReporter.java new file mode 100644 index 0000000..c867d04 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentReporter.java @@ -0,0 +1,38 @@ +package com.aventstack.extentreports.reporter; + +import com.aventstack.extentreports.IAnalysisStrategyMethod; +import com.aventstack.extentreports.ReportAggregates; +import com.aventstack.extentreports.ReportAggregatesListener; +import com.aventstack.extentreports.TestListener; + +/** + * Primary interface implemented by each reporter. This interface implements + * {@link TestListener} and {@link ReportAggregatesListener} interface to + * provide additional functionality to each reporter. + */ +public interface ExtentReporter extends TestListener, IAnalysisStrategyMethod { + + /** + * Starts passing run information to the reporter + */ + void start(); + + /** + * Stops the reporter. Ensures no information is passed to the reporter. + */ + void stop(); + + /** + * Write to or update the target source (file, database) + * + * @param reportAggregates a {@link ReportAggregates} object + */ + void flush(ReportAggregates reportAggregates); + + /** + * Get the reporter name + * + * @return reporter name + */ + String getReporterName(); +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java index 91e6e59..763e3f2 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java @@ -12,70 +12,77 @@ import freemarker.template.TemplateException; /** - * The ExtentSparkReporter creates a rich standalone spark file. It allows several - * configuration options via the config() method. + * The ExtentSparkReporter creates a rich standalone spark file. It allows + * several configuration options via the config() method. */ public class ExtentSparkReporter extends BasicFileReporter { - private static final Logger logger = Logger.getLogger(ExtentSparkReporter.class.getName()); - private static final String REPORTER_NAME = "spark"; - private static final String TEST_TEMPLATE_NAME = REPORTER_NAME + "/test.ftl"; - private static final String TAG_TEMPLATE_NAME = REPORTER_NAME + "/tag.ftl"; - private static final String EXCEPTION_TEMPLATE_NAME = REPORTER_NAME + "/exception.ftl"; - private static final String DASHBOARD_TEMPLATE_NAME = REPORTER_NAME + "/dashboard.ftl"; - private static final String[] DEFAULT_CONFIG_FILE_PATH = new String[] { "spark.properties", - "src/main/resources/spark.properties" }; - - private ExtentSparkReporterConfiguration userConfig = new ExtentSparkReporterConfiguration(this); - - public ExtentSparkReporter(String path) { - super(path); - init(DEFAULT_CONFIG_FILE_PATH, config()); - } - - public ExtentSparkReporter(File file) { - super(file); - init(DEFAULT_CONFIG_FILE_PATH, config()); - } - - public ExtentSparkReporterConfiguration config() { - return userConfig; - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - super.flush(reportAggregates); - - if (getTestList().isEmpty()) - return; - - if (enforceOfflineMode()) { - userConfig.enableOfflineMode(true); - } - - loadUserConfig(); - - try { - Template template = getFreemarkerConfig().getTemplate(TEST_TEMPLATE_NAME); - processTemplate(template, new File(destination + "index.html")); - if (!getCategoryContextInfo().getTestAttributeTestContextList().isEmpty()) { - template = getFreemarkerConfig().getTemplate(TAG_TEMPLATE_NAME); - processTemplate(template, new File(destination + "tag.html")); - } - if (!getExceptionContextInfo().getExceptionTestContextList().isEmpty()) { - template = getFreemarkerConfig().getTemplate(EXCEPTION_TEMPLATE_NAME); - processTemplate(template, new File(destination + "exception.html")); - } - template = getFreemarkerConfig().getTemplate(DASHBOARD_TEMPLATE_NAME); - processTemplate(template, new File(destination + "dashboard.html")); - } catch (IOException | TemplateException e) { - logger.log(Level.SEVERE, "An exception occurred", e); - } - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - -} + private static final Logger logger = Logger.getLogger(ExtentSparkReporter.class.getName()); + private static final String REPORTER_NAME = "spark"; + private static final String TEST_TEMPLATE_NAME = REPORTER_NAME + "/test.ftl"; + private static final String TAG_TEMPLATE_NAME = REPORTER_NAME + "/tag.ftl"; + private static final String EXCEPTION_TEMPLATE_NAME = REPORTER_NAME + "/exception.ftl"; + private static final String DASHBOARD_TEMPLATE_NAME = REPORTER_NAME + "/dashboard.ftl"; + private static final String[] DEFAULT_CONFIG_FILE_PATH = new String[] { "spark.properties", + "src/main/resources/spark.properties" }; + + private ExtentSparkReporterConfiguration externalUserConfiguration = new ExtentSparkReporterConfiguration(this); + + public ExtentSparkReporter(String path) { + super(path); + init(DEFAULT_CONFIG_FILE_PATH, config()); + } + + public ExtentSparkReporter(File file) { + super(file); + init(DEFAULT_CONFIG_FILE_PATH, config()); + } + + public ExtentSparkReporter(String path, ViewStyle viewStyle) { + this(path); + } + + public ExtentSparkReporter(File file, ViewStyle viewStyle) { + this(file); + } + + public ExtentSparkReporterConfiguration config() { + return externalUserConfiguration; + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + super.flush(reportAggregates); + if (getTestList().isEmpty()) { + return; + } + if (enforceOfflineMode()) { + externalUserConfiguration.enableOfflineMode(true); + } + + loadUserConfig(); + + try { + Template template = getFreemarkerConfig().getTemplate(TEST_TEMPLATE_NAME); + processTemplate(template, new File(getDestinationPath() + "index.html")); + if (!getCategoryContextInfo().getTestAttributeTestContext().isEmpty()) { + template = getFreemarkerConfig().getTemplate(TAG_TEMPLATE_NAME); + processTemplate(template, new File(getDestinationPath() + "tag.html")); + } + if (!getExceptionContextInfo().getExceptionTestContext().isEmpty()) { + template = getFreemarkerConfig().getTemplate(EXCEPTION_TEMPLATE_NAME); + processTemplate(template, new File(getDestinationPath() + "exception.html")); + } + template = getFreemarkerConfig().getTemplate(DASHBOARD_TEMPLATE_NAME); + processTemplate(template, new File(getDestinationPath() + "dashboard.html")); + } catch (IOException | TemplateException e) { + logger.log(Level.SEVERE, "An exception occurred", e); + } + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java deleted file mode 100644 index ac73203..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.aventstack.extentreports.reporter; - -import java.io.File; - -import com.aventstack.extentreports.ReportAggregates; - -/** - * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options - * via the config() method. - */ -public class ExtentTabularReporter - extends BasicFileReporter { - - private static final String REPORTER_NAME = "tabular"; - - public ExtentTabularReporter(String path) { - super(path); - } - - public ExtentTabularReporter(File file) { - super(file); - } - - @Override - public synchronized void flush(ReportAggregates reportAggregates) { - } - - @Override - public String getReporterName() { - return REPORTER_NAME; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java b/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java new file mode 100644 index 0000000..a4a40ce --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java @@ -0,0 +1,47 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +import com.aventstack.extentreports.ReportAggregates; +import com.aventstack.extentreports.model.Test; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class JsonFormatter extends BasicFileReporter { + + public JsonFormatter(String path) { + super(path); + } + + public JsonFormatter(File file) { + super(file); + } + + @Override + public void start() { + + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + super.flush(reportAggregates); + GsonBuilder builder = new GsonBuilder(); + //builder.registerTypeAdapter(Given.class, new GherkinModelSerializer()); + Gson gson = builder.create(); + try (FileWriter writer = new FileWriter(getFilePath())) { + List l = reportAggregates.getTestList(); + gson.toJson(l, writer); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public String getReporterName() { + return "JSON"; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ReportAppendable.java b/src/main/java/com/aventstack/extentreports/reporter/ReportAppendable.java index 335c699..ecb10da 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ReportAppendable.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ReportAppendable.java @@ -2,6 +2,6 @@ public interface ReportAppendable { - void setAppendExisting(Boolean b); + void setAppendExisting(Boolean b); -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/TestListener.java b/src/main/java/com/aventstack/extentreports/reporter/TestListener.java new file mode 100644 index 0000000..6916f46 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/TestListener.java @@ -0,0 +1,96 @@ +package com.aventstack.extentreports.reporter; + +import java.io.IOException; + +import com.aventstack.extentreports.model.Author; +import com.aventstack.extentreports.model.Category; +import com.aventstack.extentreports.model.Device; +import com.aventstack.extentreports.model.Log; +import com.aventstack.extentreports.model.ScreenCapture; +import com.aventstack.extentreports.model.Test; + +/** + * Listener methods invoked when an event occurs in the report: + * + *

      + *
    • A test or node is started
    • + *
    • A category or author is added
    • + *
    • A media object is added etc.
    • + *
    + */ +public interface TestListener { + + /** + * Invoked when a test is started using createTest() + * + * @param test {@link com.aventstack.extentreports.model.Test} object + */ + void onTestStarted(Test test); + + /** + * Invoked when a test is removed using removeTest() + * + * @param test {@link com.aventstack.extentreports.model.Test} object + */ + void onTestRemoved(Test test); + + /** + * Invoked when a node is started using createNode() + * + * @param node {@link com.aventstack.extentreports.model.Test} object + */ + void onNodeStarted(Test node); + + /** + * Invoked each time a log is added to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param log {@link com.aventstack.extentreports.model.Log} object + */ + void onLogCreated(Test test, Log log); + + /** + * Invoked each time a category is assigned to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param category {@link com.aventstack.extentreports.model.Category} object + */ + void onCategoryAssigned(Test test, Category category); + + /** + * Invoked each time an author is assigned to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param author {@link com.aventstack.extentreports.model.Author} object + */ + void onAuthorAssigned(Test test, Author author); + + /** + * Invoked each time a device is assigned to any test/node + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param device {@link com.aventstack.extentreports.model.Device} object + */ + void onDeviceAssigned(Test test, Device device); + + /** + * Invoked each time a screencapture is added to test + * + * @param test {@link com.aventstack.extentreports.model.Test} object + * @param screenCapture {@link com.aventstack.extentreports.model.ScreenCapture} + * object + * @throws IOException Exception thrown if the media object is not found + */ + void onScreenCaptureCreated(Test test, ScreenCapture screenCapture) throws IOException; + + /** + * Invoked each time a screencapture is added to log + * + * @param log {@link com.aventstack.extentreports.model.Log} object + * @param screenCapture {@link com.aventstack.extentreports.model.ScreenCapture} + * object + * @throws IOException Exception thrown if the media object is not found + */ + void onScreenCaptureCreated(Log log, ScreenCapture screenCapture) throws IOException; + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/ViewStyle.java b/src/main/java/com/aventstack/extentreports/reporter/ViewStyle.java new file mode 100644 index 0000000..9fe2666 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ViewStyle.java @@ -0,0 +1,5 @@ +package com.aventstack.extentreports.reporter; + +public enum ViewStyle { + Default, SPA +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicConfiguration.java index 7a3bdfc..cd1a10a 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicConfiguration.java @@ -2,74 +2,48 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.Optional; import com.aventstack.extentreports.Status; +import com.aventstack.extentreports.configuration.ConfigurationStore; import com.aventstack.extentreports.reporter.AbstractReporter; public abstract class BasicConfiguration { + private ConfigurationStore store = new ConfigurationStore(); private AbstractReporter reporter; - - protected List levels; - protected String reportName; - protected String timeStampFormat; - protected Map usedConfigs = new HashMap<>(); + private List levels; - protected BasicConfiguration() { } - - protected BasicConfiguration(AbstractReporter reporter) { - this.reporter = reporter; - } - - protected AbstractReporter getReporter() { - return reporter; - } - - public Map getConfigMap() { - return usedConfigs; - } + protected BasicConfiguration(AbstractReporter reporter) { + this.reporter = reporter; + } - public void setLevel(Status... level) { - if (levels == null) - levels = new ArrayList<>(); + protected AbstractReporter getReporter() { + return reporter; + } - Arrays.stream(level).forEach(levels::add); - } + public ConfigurationStore getConfigurationStore() { + return store; + } - public List getLevel() { - return levels; - } + public void setLevel(Status... level) { + if (levels == null) { + levels = new ArrayList<>(); + } + Arrays.stream(level).forEach(levels::add); + } - /** - * Gets the timestamp format - * - * @return The time stamp format - */ - public String getTimeStampFormat() { - return usedConfigs.get("timeStampFormat"); - } + public List getLevel() { + return levels; + } - /** - * Sets the timestamp format - * - * @param timeStampFormat The desired time stamp format - * See http://freemarker.org/docs/ref_builtins_date.html#ref_builtin_string_for_date - */ - public void setTimeStampFormat(String timeStampFormat) { - usedConfigs.put("timeStampFormat", timeStampFormat); - this.timeStampFormat = timeStampFormat; - } + public String getReportName() { + return (String) Optional.ofNullable(getConfigurationStore().getConfig("reportName")).orElse(null); + } - public void setReportName(String reportName) { - usedConfigs.put("reportName", reportName); - this.reportName = reportName; - } + public void setReportName(String reportName) { + store.storeConfig("reportName", reportName); + } - public String getReportName() { - return reportName; - } - -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicFileConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicFileConfiguration.java index d54268d..75432b2 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicFileConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/BasicFileConfiguration.java @@ -1,70 +1,88 @@ package com.aventstack.extentreports.reporter.configuration; +import java.util.Optional; + import com.aventstack.extentreports.reporter.AbstractReporter; /** - * Common configuration for file reporters: + * Common configuration for file based reporters * - *
      - *
    • {@link com.aventstack.extentreports.reporter.ExtentHtmlReporter}
    • - *
    */ -public class BasicFileConfiguration - extends BasicConfiguration { +public abstract class BasicFileConfiguration extends BasicConfiguration { + + protected BasicFileConfiguration(AbstractReporter reporter) { + super(reporter); + } + + /** + * Gets the timestamp format + * + * @return The time stamp format + */ + public String getTimeStampFormat() { + return (String) Optional.ofNullable(getConfigurationStore().getConfig("timeStampFormat")).orElse(null); + } + + /** + * Sets the timestamp format + * + * @param timeStampFormat The desired time stamp format See + * http://freemarker.org/docs/ref_builtins_date.html#ref_builtin_string_for_date + */ + public void setTimeStampFormat(String timeStampFormat) { + getConfigurationStore().storeConfig("timeStampFormat", timeStampFormat); + } + + /** + * Sets file encoding, eg: UTF-8 + * + * @param encoding Encoding + */ + public void setEncoding(String encoding) { + getConfigurationStore().storeConfig("encoding", encoding); + } + + public String getEncoding() { + return (String) Optional.ofNullable(getConfigurationStore().getConfig("encoding")).orElse(null); + } + + /** + * Sets the document title denoted by the title tag + * + * @param documentTitle Title + */ + public void setDocumentTitle(String documentTitle) { + getConfigurationStore().storeConfig("documentTitle", documentTitle); + } + + public String getDocumentTitle() { + return (String) Optional.ofNullable(getConfigurationStore().getConfig("documentTitle")).orElse(null); + } + + /** + * Sets CSS to be used to customize the look and feel of your report + * + * @param css CSS + */ + public void setCSS(String css) { + getConfigurationStore().storeConfig("css", css); + } + + public String getCSS() { + return (String) Optional.ofNullable(getConfigurationStore().getConfig("css")).orElse(null); + } - private String encoding; - private String docTitle; - private String css; - private String js; - - protected BasicFileConfiguration() { } - - protected BasicFileConfiguration(AbstractReporter reporter) { - super(reporter); - } - - /** - * Sets file encoding, eg: UTF-8 - * - * @param encoding Encoding - */ - public void setEncoding(String encoding) { - usedConfigs.put("encoding", encoding); - this.encoding = encoding; - } - public String getEncoding() { return encoding; } + /** + * Adds custom JavaScript + * + * @param js JavaScript + */ + public void setJS(String js) { + getConfigurationStore().storeConfig("js", js); + } - /** - * Sets the document title denoted by the title tag - * - * @param docTitle Title - */ - public void setDocumentTitle(String docTitle) { - usedConfigs.put("documentTitle", docTitle); - this.docTitle = docTitle; - } - public String getDocumentTitle() { return docTitle; } - - /** - * Sets CSS to be used to customize the look and feel of your report - * - * @param css CSS - */ - public void setCSS(String css) { - usedConfigs.put("styles", css); - this.css = css; - } - public String getCSS() { return css; } - - /** - * Adds custom JavaScript - * - * @param js JavaScript - */ - public void setJS(String js) { - usedConfigs.put("scripts", js); - this.js = js; - } - public String getJS() { return js; } + public String getJS() { + return (String) Optional.ofNullable(getConfigurationStore().getConfig("js")).orElse(null); + } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java index 7fbaec1..b7f5915 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentHtmlReporterConfiguration.java @@ -4,87 +4,87 @@ import java.util.stream.Stream; import com.aventstack.extentreports.ExtentReports; +import com.aventstack.extentreports.offline.OfflineResxDelegate; import com.aventstack.extentreports.reporter.ExtentHtmlReporter; -import com.aventstack.extentreports.resource.OfflineResxDelegate; +import com.aventstack.extentreports.reporter.ExtentSparkReporter; import com.aventstack.extentreports.utils.FileUtil; /** - * Defines configuration settings for the HTML reporter + * Defines configuration settings for the Spark reporter */ -public class ExtentHtmlReporterConfiguration - extends RichViewReporterConfiguration { +public class ExtentHtmlReporterConfiguration extends RichViewReporterConfiguration { - public ExtentHtmlReporterConfiguration(ExtentHtmlReporter reporter) { + public ExtentHtmlReporterConfiguration(ExtentHtmlReporter reporter) { super(reporter); } - - /** - * Creates the HTML report, saving all resources (css, js, fonts) in the same - * location, so the report can be viewed without an internet connection - * - * @param offline Setting to enable an offline accessible report - */ - public void enableOfflineMode(Boolean offline) { - usedConfigs.put("enableOfflineMode", String.valueOf(offline)); - usedConfigs.put("offlineDirectory", getReporter().getReporterName() + "/"); - if (offline) { - File f = getTargetDirectory(((ExtentHtmlReporter) getReporter()).getFileFile()); - String s = "/"; - String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); - resourcePackagePath += s + "offline" + s; - String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); - OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); - } - } - private File getTargetDirectory(File f) { - String dir; - if (FileUtil.isDirectory(f)) { - dir = f.getAbsolutePath().replace("\\", "/"); - } else { - dir = f.getAbsolutePath().replace("\\", "/"); - dir = new File(dir).getParent(); - } - dir += "/" + getReporter().getReporterName(); - return new File(dir); - } + /** + * Creates the HTML report, saving all resources (css, js, fonts) in the same + * location, so the report can be viewed without an internet connection + * + * @param offline Setting to enable an offline accessible report + */ + public void enableOfflineMode(Boolean offline) { + getConfigurationStore().storeConfig("enableOfflineMode", String.valueOf(offline)); + getConfigurationStore().storeConfig("offlineDirectory", getReporter().getReporterName() + "/"); + if (offline) { + File f = getTargetDirectory(((ExtentSparkReporter) getReporter()).getFileFile()); + String s = "/"; + String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); + resourcePackagePath += s + "offline" + s; + String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); + OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); + } + } + + private File getTargetDirectory(File f) { + String dir; + if (FileUtil.isDirectory(f)) { + dir = f.getAbsolutePath().replace("\\", "/"); + } else { + dir = f.getAbsolutePath().replace("\\", "/"); + dir = new File(dir).getParent(); + } + dir += "/" + getReporter().getReporterName(); + return new File(dir); + } - private String[] combine(String[]... array) { - String[] result = new String[] {}; - for (String[] arr : array) { - result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); - } - return result; - } + private String[] combine(String[]... array) { + String[] result = new String[] {}; + for (String[] arr : array) { + result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); + } + return result; + } - private String[] getJSFiles() { - String commonsPath = "commons/js/"; - String reporterPath = getReporter().getReporterName() + "/js/"; - String[] files = { reporterPath + "v3html-script.js", commonsPath + "jsontree.js" }; - return files; - } + private String[] getJSFiles() { + String commonsPath = "commons/js/"; + String reporterPath = getReporter().getReporterName() + "/js/"; + String[] files = { reporterPath + "spark-script.js", commonsPath + "jsontree.js" }; + return files; + } - private String[] getCSSFiles() { - String stylesPath = "css/"; - String reporterPath = getReporter().getReporterName() + "/" + stylesPath; - String[] files = { reporterPath + "v3html-style.css" }; - return files; - } + private String[] getCSSFiles() { + String stylesPath = "css/"; + String reporterPath = getReporter().getReporterName() + "/" + stylesPath; + String[] files = { reporterPath + "spark-style.css" }; + return files; + } - private String[] getIconFiles() { - String path = "commons/css/icons/"; - String iconDirPath = "material/"; - String[] files = { path + "material-icons.css", path + iconDirPath + "MaterialIcons-Regular.eot", - path + iconDirPath + "MaterialIcons-Regular.ijmap", path + iconDirPath + "MaterialIcons-Regular.svg", - path + iconDirPath + "MaterialIcons-Regular.ttf", path + iconDirPath + "MaterialIcons-Regular.woff", - path + iconDirPath + "MaterialIcons-Regular.woff2" }; - return files; - } + private String[] getIconFiles() { + String path = "commons/css/icons/"; + String iconDirPath = "fontawesome/"; + String[] files = { path + "font-awesome.min.css", path + iconDirPath + "fontawesome-webfont.eot", + path + iconDirPath + "fontawesome-webfont.svg", path + iconDirPath + "fontawesome-webfont.ttf", + path + iconDirPath + "fontawesome-webfont.woff", path + iconDirPath + "fontawesome-webfont.woff2", + path + iconDirPath + "FontAwesome.otf" }; + return files; + } - private String[] getImgFiles() { - String path = "commons/img/"; - String[] files = { path + "logo.png" }; - return files; - } + private String[] getImgFiles() { + String path = "commons/img/"; + String[] files = { path + "logo.png" }; + return files; + } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerFormatterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerFormatterConfiguration.java deleted file mode 100644 index b6e0fa5..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerFormatterConfiguration.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.aventstack.extentreports.reporter.configuration; - -import java.io.File; -import java.util.stream.Stream; - -import com.aventstack.extentreports.ExtentReports; -import com.aventstack.extentreports.reporter.AbstractReporter; -import com.aventstack.extentreports.reporter.ExtentLoggerReporter; -import com.aventstack.extentreports.resource.OfflineResxDelegate; -import com.aventstack.extentreports.utils.FileUtil; - -/** - * Defines configuration settings for the HTML reporter - */ -public class ExtentLoggerFormatterConfiguration - extends RichViewReporterConfiguration { - - public ExtentLoggerFormatterConfiguration(AbstractReporter reporter) { - super(reporter); - } - - /** - * Creates the HTML report, saving all resources (css, js, fonts) in the same location, so the - * report can be viewed without an internet connection - * - * @param offline Setting to enable an offline accessible report - */ - public void enableOfflineMode(Boolean offline) { - usedConfigs.put("enableOfflineMode", String.valueOf(offline)); - usedConfigs.put("offlineDirectory", getReporter().getReporterName() + "/"); - if (offline) { - File f = getTargetDirectory(((ExtentLoggerReporter)getReporter()).getFileFile()); - String s = "/"; - String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); - resourcePackagePath += s + "offline" + s; - String[] resx = combine(getJSFiles(), - getCSSFiles(), - getIconFiles(), - getImgFiles()); - OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); - } - } - - private File getTargetDirectory(File f) { - String dir; - if (FileUtil.isDirectory(f)) { - dir = f.getAbsolutePath().replace("\\", "/"); - } else { - dir = f.getAbsolutePath().replace("\\", "/"); - dir = new File(dir).getParent(); - } - dir += "/" + getReporter().getReporterName(); - return new File(dir); - } - - private String[] combine(String[]... array) { - String[] result = new String[] {}; - for (String[] arr : array) { - result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); - } - return result; - } - - private String[] getJSFiles() { - String commonsPath = "commons/js/"; - String reporterPath = getReporter().getReporterName() + "/js/"; - String[] files = { - commonsPath + "attr.js", - commonsPath + "dashboard.js", - reporterPath + "logger-scripts.js" - }; - return files; - } - - private String[] getCSSFiles() { - String stylesPath = "css/"; - String reporterPath = getReporter().getReporterName() + "/" + stylesPath + "/"; - String[] files = { - reporterPath + "logger-style.css", - }; - return files; - } - - private String[] getIconFiles() { - String path = "commons/css/icons/"; - String iconDirPath = "fontawesome/"; - String[] files = { - path + "font-awesome.min.css", - path + iconDirPath + "fontawesome-webfont.eot", - path + iconDirPath + "fontawesome-webfont.svg", - path + iconDirPath + "fontawesome-webfont.ttf", - path + iconDirPath + "fontawesome-webfont.woff", - path + iconDirPath + "fontawesome-webfont.woff2", - path + iconDirPath + "FontAwesome.otf", - }; - return files; - } - - private String[] getImgFiles() { - String path = "commons/img/"; - String[] files = { - path + "logo.png" - }; - return files; - } - -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerReporterConfiguration.java new file mode 100644 index 0000000..781bcca --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentLoggerReporterConfiguration.java @@ -0,0 +1,90 @@ +package com.aventstack.extentreports.reporter.configuration; + +import java.io.File; +import java.util.stream.Stream; + +import com.aventstack.extentreports.ExtentReports; +import com.aventstack.extentreports.offline.OfflineResxDelegate; +import com.aventstack.extentreports.reporter.AbstractReporter; +import com.aventstack.extentreports.reporter.ExtentLoggerReporter; +import com.aventstack.extentreports.utils.FileUtil; + +/** + * Defines configuration settings for the HTML reporter + */ +public class ExtentLoggerReporterConfiguration extends RichViewReporterConfiguration { + + public ExtentLoggerReporterConfiguration(AbstractReporter reporter) { + super(reporter); + } + + /** + * Creates the HTML report, saving all resources (css, js, fonts) in the same + * location, so the report can be viewed without an internet connection + * + * @param offline Setting to enable an offline accessible report + */ + public void enableOfflineMode(Boolean offline) { + getConfigurationStore().storeConfig("enableOfflineMode", String.valueOf(offline)); + getConfigurationStore().storeConfig("offlineDirectory", getReporter().getReporterName() + "/"); + if (offline) { + File f = getTargetDirectory(((ExtentLoggerReporter) getReporter()).getFileFile()); + String s = "/"; + String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); + resourcePackagePath += s + "offline" + s; + String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); + OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); + } + } + + private File getTargetDirectory(File f) { + String dir; + if (FileUtil.isDirectory(f)) { + dir = f.getAbsolutePath().replace("\\", "/"); + } else { + dir = f.getAbsolutePath().replace("\\", "/"); + dir = new File(dir).getParent(); + } + dir += "/" + getReporter().getReporterName(); + return new File(dir); + } + + private String[] combine(String[]... array) { + String[] result = new String[] {}; + for (String[] arr : array) { + result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); + } + return result; + } + + private String[] getJSFiles() { + String commonsPath = "commons/js/"; + String reporterPath = getReporter().getReporterName() + "/js/"; + String[] files = { commonsPath + "attr.js", commonsPath + "dashboard.js", reporterPath + "logger-scripts.js" }; + return files; + } + + private String[] getCSSFiles() { + String stylesPath = "css/"; + String reporterPath = getReporter().getReporterName() + "/" + stylesPath + "/"; + String[] files = { reporterPath + "logger-style.css", }; + return files; + } + + private String[] getIconFiles() { + String path = "commons/css/icons/"; + String iconDirPath = "fontawesome/"; + String[] files = { path + "font-awesome.min.css", path + iconDirPath + "fontawesome-webfont.eot", + path + iconDirPath + "fontawesome-webfont.svg", path + iconDirPath + "fontawesome-webfont.ttf", + path + iconDirPath + "fontawesome-webfont.woff", path + iconDirPath + "fontawesome-webfont.woff2", + path + iconDirPath + "FontAwesome.otf", }; + return files; + } + + private String[] getImgFiles() { + String path = "commons/img/"; + String[] files = { path + "logo.png" }; + return files; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java index cfbc8db..2ba9185 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/ExtentSparkReporterConfiguration.java @@ -4,87 +4,86 @@ import java.util.stream.Stream; import com.aventstack.extentreports.ExtentReports; +import com.aventstack.extentreports.offline.OfflineResxDelegate; import com.aventstack.extentreports.reporter.ExtentSparkReporter; -import com.aventstack.extentreports.resource.OfflineResxDelegate; import com.aventstack.extentreports.utils.FileUtil; /** * Defines configuration settings for the Spark reporter */ -public class ExtentSparkReporterConfiguration - extends RichViewReporterConfiguration { +public class ExtentSparkReporterConfiguration extends RichViewReporterConfiguration { - public ExtentSparkReporterConfiguration(ExtentSparkReporter reporter) { + public ExtentSparkReporterConfiguration(ExtentSparkReporter reporter) { super(reporter); } - - /** - * Creates the HTML report, saving all resources (css, js, fonts) in the same - * location, so the report can be viewed without an internet connection - * - * @param offline Setting to enable an offline accessible report - */ - public void enableOfflineMode(Boolean offline) { - usedConfigs.put("enableOfflineMode", String.valueOf(offline)); - usedConfigs.put("offlineDirectory", getReporter().getReporterName() + "/"); - if (offline) { - File f = getTargetDirectory(((ExtentSparkReporter) getReporter()).getFileFile()); - String s = "/"; - String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); - resourcePackagePath += s + "offline" + s; - String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); - OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); - } - } - private File getTargetDirectory(File f) { - String dir; - if (FileUtil.isDirectory(f)) { - dir = f.getAbsolutePath().replace("\\", "/"); - } else { - dir = f.getAbsolutePath().replace("\\", "/"); - dir = new File(dir).getParent(); - } - dir += "/" + getReporter().getReporterName(); - return new File(dir); - } + /** + * Creates the HTML report, saving all resources (css, js, fonts) in the same + * location, so the report can be viewed without an internet connection + * + * @param offline Setting to enable an offline accessible report + */ + public void enableOfflineMode(Boolean offline) { + getConfigurationStore().storeConfig("enableOfflineMode", String.valueOf(offline)); + getConfigurationStore().storeConfig("offlineDirectory", getReporter().getReporterName() + "/"); + if (offline) { + File f = getTargetDirectory(((ExtentSparkReporter) getReporter()).getFileFile()); + String s = "/"; + String resourcePackagePath = ExtentReports.class.getPackage().getName().replace(".", s); + resourcePackagePath += s + "offline" + s; + String[] resx = combine(getJSFiles(), getCSSFiles(), getIconFiles(), getImgFiles()); + OfflineResxDelegate.saveOfflineResources(resourcePackagePath, resx, f.getAbsolutePath()); + } + } + + private File getTargetDirectory(File f) { + String dir; + if (FileUtil.isDirectory(f)) { + dir = f.getAbsolutePath().replace("\\", "/"); + } else { + dir = f.getAbsolutePath().replace("\\", "/"); + dir = new File(dir).getParent(); + } + dir += "/" + getReporter().getReporterName(); + return new File(dir); + } - private String[] combine(String[]... array) { - String[] result = new String[] {}; - for (String[] arr : array) { - result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); - } - return result; - } + private String[] combine(String[]... array) { + String[] result = new String[] {}; + for (String[] arr : array) { + result = Stream.of(result, arr).flatMap(Stream::of).toArray(String[]::new); + } + return result; + } - private String[] getJSFiles() { - String commonsPath = "commons/js/"; - String reporterPath = getReporter().getReporterName() + "/js/"; - String[] files = { reporterPath + "spark-script.js", commonsPath + "jsontree.js" }; - return files; - } + private String[] getJSFiles() { + String commonsPath = "commons/js/"; + String reporterPath = getReporter().getReporterName() + "/js/"; + String[] files = { reporterPath + "spark-script.js", commonsPath + "jsontree.js" }; + return files; + } - private String[] getCSSFiles() { - String stylesPath = "css/"; - String reporterPath = getReporter().getReporterName() + "/" + stylesPath; - String[] files = { reporterPath + "spark-style.css" }; - return files; - } + private String[] getCSSFiles() { + String stylesPath = "css/"; + String reporterPath = getReporter().getReporterName() + "/" + stylesPath; + String[] files = { reporterPath + "spark-style.css" }; + return files; + } - private String[] getIconFiles() { - String path = "commons/css/icons/"; - String iconDirPath = "fontawesome/"; - String[] files = { path + "font-awesome.min.css", path + iconDirPath + "fontawesome-webfont.eot", - path + iconDirPath + "fontawesome-webfont.svg", path + iconDirPath + "fontawesome-webfont.ttf", - path + iconDirPath + "fontawesome-webfont.woff", path + iconDirPath + "fontawesome-webfont.woff2", - path + iconDirPath + "FontAwesome.otf" }; - return files; - } + private String[] getIconFiles() { + String path = "commons/css/icons/"; + String iconDirPath = "fontawesome/"; + String[] files = { path + "font-awesome.min.css", path + iconDirPath + "fontawesome-webfont.eot", + path + iconDirPath + "fontawesome-webfont.svg", path + iconDirPath + "fontawesome-webfont.ttf", + path + iconDirPath + "fontawesome-webfont.woff", path + iconDirPath + "fontawesome-webfont.woff2", + path + iconDirPath + "FontAwesome.otf" }; + return files; + } - private String[] getImgFiles() { - String path = "commons/img/"; - String[] files = { path + "logo.png" }; - return files; - } + private String[] getImgFiles() { + String path = "commons/img/"; + String[] files = { path + "logo.png" }; + return files; + } -} +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/IReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/IReporterConfiguration.java index f7fef8b..9cac8d2 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/IReporterConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/IReporterConfiguration.java @@ -1,3 +1,5 @@ package com.aventstack.extentreports.reporter.configuration; -public interface IReporterConfiguration { } +public interface IReporterConfiguration { + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/Protocol.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/Protocol.java index 225e39f..6818afa 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/Protocol.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/Protocol.java @@ -1,9 +1,8 @@ package com.aventstack.extentreports.reporter.configuration; /** - * Protocol used to download CDN css/js resources for HTML reports + * Protocol used to download CDN css/js resources for HTML reports */ public enum Protocol { - HTTP, - HTTPS -} + HTTP, HTTPS +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/ResourceCDN.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/ResourceCDN.java deleted file mode 100644 index e9de0bd..0000000 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/ResourceCDN.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.aventstack.extentreports.reporter.configuration; - -/** - * Allows selecting a CDN/resource loader for your FileReporter - * - * Note: Some hosts do not allow loading resources via HTTPS protocol: - * - *
      - *
    • ExtentReports
    • - *
    - * - */ -public enum ResourceCDN { - GITHUB, - EXTENTREPORTS -} diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/RichViewReporterConfiguration.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/RichViewReporterConfiguration.java index d627d10..f1c468b 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/RichViewReporterConfiguration.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/RichViewReporterConfiguration.java @@ -6,91 +6,56 @@ * Contains configuration for rich reporters such as Avent, Tabular, Cards etc. * */ -public abstract class RichViewReporterConfiguration - extends BasicFileConfiguration - implements IReporterConfiguration { - - private Protocol protocol; - private Theme theme; - +public abstract class RichViewReporterConfiguration extends BasicFileConfiguration implements IReporterConfiguration { + protected RichViewReporterConfiguration(AbstractReporter reporter) { super(reporter); } - - /** - * Sets the protocol of accessing CSS/JS resources from CDN - * - *

    - * Default protocol value: HTTPS - *

    - * - * @param protocol Protocol, HTTPS or HTTP - */ - public void setProtocol(Protocol protocol) { - usedConfigs.put("protocol", String.valueOf(protocol).toLowerCase()); - this.protocol = protocol; - } - - public Protocol getProtocol() { - return protocol; - } - - /** - * Sets the {@link Theme} of the report - * - * @param theme {@link Theme} - */ - public void setTheme(Theme theme) { - usedConfigs.put("theme", String.valueOf(theme).toLowerCase()); - this.theme = theme; - } - - public Theme getTheme() { - return theme; - } - - /** - * Enable or disable the Timeline section in the Dashboard view - * - * @param v Setting to enable or disable the Timeline section in the Dashboard - * view - */ - public void enableTimeline(boolean v) { - usedConfigs.put("enableTimeline", String.valueOf(v)); - } - + /** - * Setting to automatically store screen shots relative to the path. This method - * also sets the new relative path as a link from the report. Example: - * - *
    -	 * /
    -	 *   Report.html
    -	 *   Report.0
    -	 *     - 1.png
    -	 *     - 2.png
    -	 *   Report.1
    -	 *     - 1.png
    -	 *     - 2.png
    -	 * 
    + * Sets the protocol of accessing CSS/JS resources from CDN * *

    - * Report.0 directory will contain media from the 1st run. Report.1 directory - * will contain media from the 2nd run. + * Default protocol value: HTTPS *

    * - * @param v Setting to enable this feature + * @param protocol Protocol, HTTPS or HTTP */ - public void setAutoCreateRelativePathMedia(boolean v) { - usedConfigs.put("autoCreateRelativePathMedia", String.valueOf(v)); + public void setProtocol(Protocol protocol) { + getConfigurationStore().storeConfig("protocol", String.valueOf(protocol).toLowerCase()); + } + + public Protocol getProtocol() { + if (getConfigurationStore().containsConfig("protocol")) { + return (Protocol) getConfigurationStore().getConfig("protocol"); + } + return null; } - + /** - * Allows selecting a CDN/resource loader for your FileReporter + * Sets the {@link Theme} of the report * - * @param resourceCDN the {@link ResourceCDN} + * @param theme {@link Theme} + */ + public void setTheme(Theme theme) { + getConfigurationStore().storeConfig("theme", String.valueOf(theme).toLowerCase()); + } + + public Theme getTheme() { + if (getConfigurationStore().containsConfig("theme")) { + return Theme.valueOf(getConfigurationStore().getConfig("theme").toString()); + } + return null; + } + + /** + * Enable or disable the Timeline section in the Dashboard view + * + * @param v Setting to enable or disable the Timeline section in the Dashboard + * view */ - public void setResourceCDN(ResourceCDN resourceCDN) { - usedConfigs.put("resourceCDN", String.valueOf(resourceCDN).toLowerCase()); - } -} + public void enableTimeline(boolean v) { + getConfigurationStore().storeConfig("enableTimeline", String.valueOf(v).toLowerCase()); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/configuration/Theme.java b/src/main/java/com/aventstack/extentreports/reporter/configuration/Theme.java index c3e1bdc..7f0a8dc 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/configuration/Theme.java +++ b/src/main/java/com/aventstack/extentreports/reporter/configuration/Theme.java @@ -1,9 +1,8 @@ package com.aventstack.extentreports.reporter.configuration; /** - * Available themes for the HTML reporter + * Available themes for the HTML reporter */ public enum Theme { - STANDARD, - DARK -} + STANDARD, DARK +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/templating/FreemarkerTemplate.java b/src/main/java/com/aventstack/extentreports/templating/FreemarkerTemplate.java new file mode 100644 index 0000000..7ce39e2 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/templating/FreemarkerTemplate.java @@ -0,0 +1,59 @@ +package com.aventstack.extentreports.templating; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Map; + +import com.aventstack.extentreports.io.FileWriterBuffered; + +import freemarker.core.ParseException; +import freemarker.template.Configuration; +import freemarker.template.MalformedTemplateNameException; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import freemarker.template.TemplateNotFoundException; + +public class FreemarkerTemplate { + + private TemplateConfig config = new TemplateConfig(); + private Configuration freemarkerConfiguration; + + public FreemarkerTemplate(Configuration freemarkerConfiguration) { + this.freemarkerConfiguration = freemarkerConfiguration; + } + + public FreemarkerTemplate(Class clazz, String encoding) { + freemarkerConfiguration = config.getFreemarkerConfig(clazz, encoding); + } + + public FreemarkerTemplate(Class clazz, String basePackagePath, String encoding) { + freemarkerConfiguration = config.getFreemarkerConfig(clazz, basePackagePath, encoding); + } + + public Template createTemplate(String templatePath) + throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { + return freemarkerConfiguration.getTemplate(templatePath); + } + + public String getSource(Template template, Map templateMap) throws TemplateException, IOException { + String source = processTemplate(template, templateMap); + return source; + } + + public void writeTemplate(Template template, Map templateMap, File outputFile) + throws TemplateException, IOException { + String source = getSource(template, templateMap); + FileWriterBuffered.getInstance().write(outputFile, source); + } + + private String processTemplate(Template template, Map templateMap) + throws TemplateException, IOException { + StringWriter out = new StringWriter(); + template.process(templateMap, out); + String source = out.toString(); + out.close(); + return source; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/templating/TemplateConfig.java b/src/main/java/com/aventstack/extentreports/templating/TemplateConfig.java new file mode 100644 index 0000000..508bc00 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/templating/TemplateConfig.java @@ -0,0 +1,18 @@ +package com.aventstack.extentreports.templating; + +import freemarker.template.Configuration; + +public class TemplateConfig { + + public Configuration getFreemarkerConfig(Class clazz, String basePackagePath, String encoding) { + Configuration cfg = new Configuration(Configuration.VERSION_2_3_29); + cfg.setClassForTemplateLoading(clazz, basePackagePath); + cfg.setDefaultEncoding(encoding); + return cfg; + } + + public Configuration getFreemarkerConfig(Class clazz, String encoding) { + return getFreemarkerConfig(clazz, "/", encoding); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/utils/DateUtil.java b/src/main/java/com/aventstack/extentreports/utils/DateUtil.java deleted file mode 100644 index 27c90c1..0000000 --- a/src/main/java/com/aventstack/extentreports/utils/DateUtil.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.aventstack.extentreports.utils; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class DateUtil { - - private static final Logger logger = Logger.getLogger(DateUtil.class.getName()); - - private DateUtil() { } - - public static Date parse(String dt, String format) { - DateFormat df = new SimpleDateFormat(format); - - try { - return df.parse(dt); - } catch (Exception e) { - logger.log(Level.SEVERE, "", e); - return null; - } - } - -} diff --git a/src/main/java/com/aventstack/extentreports/utils/ExceptionUtil.java b/src/main/java/com/aventstack/extentreports/utils/ExceptionUtil.java index b4d7803..81c03eb 100644 --- a/src/main/java/com/aventstack/extentreports/utils/ExceptionUtil.java +++ b/src/main/java/com/aventstack/extentreports/utils/ExceptionUtil.java @@ -6,27 +6,28 @@ import java.util.regex.Pattern; public class ExceptionUtil { - - private ExceptionUtil() { } - - public static String getStackTrace(Throwable t) { - if (t == null) - return null; - - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - return sw.toString(); - } - - public static String getExceptionHeadline(Throwable t) { - Pattern pattern = Pattern.compile("([\\w\\.]+)(:.*)?"); - String stackTrace = getStackTrace(t); - Matcher matcher = pattern.matcher(stackTrace); - - if (matcher.find()) - return matcher.group(1); - - return null; - } -} + + private ExceptionUtil() { + } + + public static String getStackTrace(Throwable t) { + if (t == null) + return null; + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + return sw.toString(); + } + + public static String getExceptionHeadline(Throwable t) { + Pattern pattern = Pattern.compile("([\\w\\.]+)(:.*)?"); + String stackTrace = getStackTrace(t); + Matcher matcher = pattern.matcher(stackTrace); + + if (matcher.find()) + return matcher.group(1); + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/utils/FileUtil.java b/src/main/java/com/aventstack/extentreports/utils/FileUtil.java index 44790ef..32a1a62 100644 --- a/src/main/java/com/aventstack/extentreports/utils/FileUtil.java +++ b/src/main/java/com/aventstack/extentreports/utils/FileUtil.java @@ -6,71 +6,72 @@ import java.util.Arrays; public class FileUtil { - - private FileUtil() { } - - public static String getFileName(File f) { - if (f == null || !f.exists()) - return ""; - return f.getName(); - } - - public static String getFileName(String path) { - return getFileName(new File(path)); - } - - public static String getFileNameWithoutExtension(File f) { - String name = f.getName(); - int i = name.lastIndexOf('.'); - if (i > 0) - return name.substring(0, i); - - return name; - } - - public static String getFileNameWithoutExtension(String filePath) { - return getFileNameWithoutExtension(new File(filePath)); - } - - public static String getExtension(File f) { - String name = f.getName(); - int i = name.lastIndexOf('.'); - if (i > 0) - return name.substring(i + 1); - return ""; - } - - public static String getExtension(String filePath) { - return getExtension(new File(filePath)); - } - - public static Boolean isDirectory(String filePath) { - return isDirectory(new File(filePath)); - } - - public static Boolean isDirectory(File file) { - Path path = file.toPath(); - return Files.isDirectory(path); - } - - public static void createDirectory(String path) { - new File(path).mkdirs(); - } - - public static void createDirectory(String[] path) { - Arrays.asList(path).forEach(FileUtil::createDirectory); - } - - public static Boolean fileExists(String path) { - File f = new File(path); - return f.exists() && !f.isDirectory(); - } - - public static long getFileSize(String path) { - if (path == null) - return 0; - File f = new File(path); - return f.exists() ? f.length() : 0; - } - -} + + private FileUtil() { + } + + public static String getFileName(File f) { + if (f == null || !f.exists()) + return ""; + return f.getName(); + } + + public static String getFileName(String path) { + return getFileName(new File(path)); + } + + public static String getFileNameWithoutExtension(File f) { + String name = f.getName(); + int i = name.lastIndexOf('.'); + if (i > 0) + return name.substring(0, i); + + return name; + } + + public static String getFileNameWithoutExtension(String filePath) { + return getFileNameWithoutExtension(new File(filePath)); + } + + public static String getExtension(File f) { + String name = f.getName(); + int i = name.lastIndexOf('.'); + if (i > 0) + return name.substring(i + 1); + return ""; + } + + public static String getExtension(String filePath) { + return getExtension(new File(filePath)); + } + + public static Boolean isDirectory(String filePath) { + return isDirectory(new File(filePath)); + } + + public static Boolean isDirectory(File file) { + Path path = file.toPath(); + return Files.isDirectory(path); + } + + public static void createDirectory(String path) { + new File(path).mkdirs(); + } + + public static void createDirectory(String[] path) { + Arrays.asList(path).forEach(FileUtil::createDirectory); + } + + public static Boolean fileExists(String path) { + File f = new File(path); + return f.exists() && !f.isDirectory(); + } + + public static long getFileSize(String path) { + if (path == null) + return 0; + File f = new File(path); + return f.exists() ? f.length() : 0; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/utils/IntUtils.java b/src/main/java/com/aventstack/extentreports/utils/IntUtils.java deleted file mode 100644 index 200cd7e..0000000 --- a/src/main/java/com/aventstack/extentreports/utils/IntUtils.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.aventstack.extentreports.utils; - -public class IntUtils { - - private IntUtils() { - } - - public static boolean tryParseInt(String value) { - try { - Integer.parseInt(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - -} diff --git a/src/main/java/com/aventstack/extentreports/utils/MongoUtil.java b/src/main/java/com/aventstack/extentreports/utils/MongoUtil.java index 1810e9e..085b7dc 100644 --- a/src/main/java/com/aventstack/extentreports/utils/MongoUtil.java +++ b/src/main/java/com/aventstack/extentreports/utils/MongoUtil.java @@ -4,11 +4,12 @@ import org.bson.types.ObjectId; public class MongoUtil { - - private MongoUtil() { } - - public static ObjectId getId(Document doc) { - return (ObjectId) doc.get("_id"); - } - -} + + private MongoUtil() { + } + + public static ObjectId getId(Document doc) { + return (ObjectId) doc.get("_id"); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/utils/Reader.java b/src/main/java/com/aventstack/extentreports/utils/Reader.java deleted file mode 100644 index 9bff617..0000000 --- a/src/main/java/com/aventstack/extentreports/utils/Reader.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.aventstack.extentreports.utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class Reader { - - final static Logger logger = Logger.getLogger(Reader.class.getName()); - - private Reader() { } - - public static String readAllText(String filePath) { - File file = new File(filePath); - - if (file.exists()) { - byte[] data; - - try (FileInputStream fis = new FileInputStream(file)) { - data = new byte[(int)file.length()]; - fis.read(data); - - return new String(data, "UTF-8"); - } - catch (IOException e) { - logger.log(Level.SEVERE, filePath, e); - } - } - - return null; - } - - public static String readAllText(File file) { - return readAllText(file.getAbsolutePath()); - } -} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/utils/ResourceUtil.java b/src/main/java/com/aventstack/extentreports/utils/ResourceUtil.java deleted file mode 100644 index c8aeebe..0000000 --- a/src/main/java/com/aventstack/extentreports/utils/ResourceUtil.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.aventstack.extentreports.utils; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -public class ResourceUtil { - - public static void moveResource(String resourcePath, String copyPath) { - if (copyPath != null) - copyPath = copyPath.replace("\\", "/"); - if (resourcePath != null) - resourcePath = resourcePath.replace("\\", "/"); - - try { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - InputStream in = classLoader.getResourceAsStream(resourcePath); - - FileOutputStream out = new FileOutputStream(copyPath); - - byte[] b = new byte[1024]; - int noOfBytes = 0; - - while( (noOfBytes = in.read(b)) != -1 ) { - out.write(b, 0, noOfBytes); - } - - in.close(); - out.close(); - } - catch (FileNotFoundException e) { - e.printStackTrace(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - - public static void moveBinaryFile(String resourcePath, String copyPath) { - URI uri = new File(resourcePath).toURI(); - Path path = Paths.get(uri); - try { - Files.copy(path, new File(copyPath).toPath(), StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/src/main/java/com/aventstack/extentreports/utils/StringUtil.java b/src/main/java/com/aventstack/extentreports/utils/StringUtil.java index 1f2d125..8edf83b 100644 --- a/src/main/java/com/aventstack/extentreports/utils/StringUtil.java +++ b/src/main/java/com/aventstack/extentreports/utils/StringUtil.java @@ -1,14 +1,15 @@ package com.aventstack.extentreports.utils; public class StringUtil { - - private StringUtil() { } - - public static String capitalize(String s) { - return Character.toLowerCase(s.charAt(0)) + s.substring(1); - } - - public static boolean isNotNullOrEmpty (String str) { + + private StringUtil() { + } + + public static String capitalize(String s) { + return Character.toLowerCase(s.charAt(0)) + s.substring(1); + } + + public static boolean isNotNullOrEmpty(String str) { return str != null && !str.trim().isEmpty(); - } -} + } +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/utils/Writer.java b/src/main/java/com/aventstack/extentreports/utils/Writer.java deleted file mode 100644 index ac0844d..0000000 --- a/src/main/java/com/aventstack/extentreports/utils/Writer.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.aventstack.extentreports.utils; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class Writer { - - private static class WriterInstance { - static final Writer INSTANCE = new Writer(); - - private WriterInstance() { } - } - - static final Logger logger = Logger.getLogger(Writer.class.getName()); - - private Writer() { } - - public synchronized void write(final File f, String text) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(f))) { - writer.write(text); - } - catch (Exception e) { - logger.log(Level.SEVERE, f.getPath(), e); - } - } - - public static Writer getInstance() { - return WriterInstance.INSTANCE; - } - -} \ No newline at end of file diff --git a/src/main/resources/com/aventstack/extentreports/markup/codeblock.ftl b/src/main/resources/com/aventstack/extentreports/markup/codeblock.ftl new file mode 100644 index 0000000..a0e209c --- /dev/null +++ b/src/main/resources/com/aventstack/extentreports/markup/codeblock.ftl @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/main/resources/com/aventstack/extentreports/markup/codeblock.json.ftl b/src/main/resources/com/aventstack/extentreports/markup/codeblock.json.ftl new file mode 100644 index 0000000..36074fa --- /dev/null +++ b/src/main/resources/com/aventstack/extentreports/markup/codeblock.json.ftl @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard.ftl index cf39025..11facfe 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard.ftl @@ -178,7 +178,7 @@
    - <#if config.getValue("enableTimeline")=='true'> + <#if config.getConfig("enableTimeline")=='true'>
    diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-css.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-css.ftl index ab42914..00d17c4 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-css.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-css.ftl @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-js.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-js.ftl index 29aafbb..0a02f3f 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-js.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-inject-js.ftl @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl index e7af660..a30a9c4 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl @@ -33,7 +33,7 @@ <#assign n=test level=n.level> <#if level!=0><#assign n=test.parent><#if n.level!=0><#assign n=n.parent><#if n.level!=0><#assign n=n.parent> - + ${test.status} ${test.name} <#if level!=0>
    ${test.parent.name} ${test.runDuration}c diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl index 4afd7a0..f8c26f2 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl @@ -1,13 +1,13 @@ -<#assign config=report.configContext> +<#assign config=report.configurationStore> <#assign offline="false"> -<#if config.getValue("enableOfflineMode")??><#assign offline=config.getValue("enableOfflineMode")> +<#if config.getConfig("enableOfflineMode")??><#assign offline=config.getConfig("enableOfflineMode")> -<#assign theme=config.containsKey('theme')?then(config.getValue('theme')?lower_case, '')> +<#assign theme=config.containsConfig('theme')?then(config.getConfig('theme')?lower_case, '')> <#assign systemAttributeContext=report.getSystemAttributeContext().getSystemAttributeList()> -<#assign categoryContext=report.getCategoryContextInfo().getTestAttributeTestContextList()> -<#assign authorContext=report.getAuthorContextInfo().getTestAttributeTestContextList()> -<#assign deviceContext=report.getDeviceContextInfo().getTestAttributeTestContextList()> -<#assign exceptionContext=report.getExceptionContextInfo().getExceptionTestContextList()> +<#assign categoryContext=report.getCategoryContextInfo().getTestAttributeTestContext()> +<#assign authorContext=report.getAuthorContextInfo().getTestAttributeTestContext()> +<#assign deviceContext=report.getDeviceContextInfo().getTestAttributeTestContext()> +<#assign exceptionContext=report.getExceptionContextInfo().getExceptionTestContext()> <#assign reportType="" parentHeading="Tests" childHeading="Steps" grandChildHeading="" size=2> <#if report.analysisStrategy=="SUITE"> @@ -23,4 +23,4 @@ <#assign parentHeading="Class" childHeading="Methods" grandChildHeading="" size=2> -<#assign timeStampFormat=config.getValue('timeStampFormat')> \ No newline at end of file +<#assign timeStampFormat=config.getConfig('timeStampFormat')> \ No newline at end of file diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl index ec4f38f..27ac388 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl @@ -26,9 +26,9 @@
    <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/js/"> - <#if offline=="true"><#assign p=config.getValue("offlineDirectory")> + <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getValue("scripts")?has_content> + <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> <#include "../commons/commons-dashboard-scripts.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl index 613aac4..c1bd918 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl @@ -48,9 +48,9 @@
    <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/js/"> - <#if offline=="true"><#assign p=config.getValue("offlineDirectory")> + <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getValue("scripts")?has_content> + <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl index d53e3e5..4b34763 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl @@ -56,9 +56,9 @@ <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/js/"> - <#if offline=="true"><#assign p=config.getValue("offlineDirectory")> + <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getValue("scripts")?has_content> + <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl index 0e3ea58..e613000 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl @@ -74,7 +74,7 @@ -
  • ${config.getValue("reportName")}
  • +
  • ${config.getConfig("reportName")}
  • 4.0
  • @@ -160,9 +160,9 @@ <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/logger/js/"> - <#if offline=="true"><#assign p=config.getValue("offlineDirectory")> + <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getValue("scripts")?has_content> + <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/dashboard.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/dashboard.ftl index c831d74..04e4a4d 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/dashboard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/dashboard.ftl @@ -1,13 +1,5 @@ <#include "../commons/commons-variables.ftl"> -<#assign systemAttributeContext=report.getSystemAttributeContext().getSystemAttributeList()> -<#assign authorContext=report.getAuthorContextInfo().getTestAttributeTestContextList()> -<#assign categoryContext=report.getCategoryContextInfo().getTestAttributeTestContextList()> -<#assign deviceContext=report.getDeviceContextInfo().getTestAttributeTestContextList()> -<#assign exceptionContext=report.getExceptionContextInfo().getExceptionTestContextList()> -<#assign config=report.getConfigContext()> -<#assign timeStampFormat = config.getValue('timeStampFormat')> - <#assign boxsize='col-md-12'> <#if report.reportStatusStats.childCount!=0> <#assign boxsize='col-sm-12 col-md-6'> @@ -185,7 +177,7 @@ - <#if config.getValue("enableTimeline")=='true'> + <#if config.getConfig("enableTimeline")=='true'>
    @@ -259,7 +251,7 @@ - <#list report.categoryContextInfo.testAttributeTestContextList as category> + <#list categoryContext as category> ${category.name} ${category.passed} @@ -386,11 +378,11 @@ exceptionsGrandChild: ${ report.reportStatusStats.grandChildCountExceptions?c }, }; - <#if config.getValue("enableTimeline")=='true'> + <#if config.getConfig("enableTimeline")=='true'> + <#else> -<#if config.containsKey("scripts") && config.getValue("scripts")?has_content> +<#if config.containsConfig("js") && config.getConfig("js")?has_content> <#include "../../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/standard-content.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/standard-content.ftl index 17f4146..0cbdf50 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/standard-content.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/standard-content.ftl @@ -1,12 +1,12 @@ -<#if test.hasLog()> +<#if TestService.testHasLog(test)>
    <@log test=test />
    -<#if test.hasScreenCapture()> +<#if TestService.testHasScreenCapture(test)>
      - <#list test.screenCaptureList as sc> + <#list test.screenCaptureContext.all as sc>
    • @@ -27,7 +27,7 @@
    -<#if test.hasChildren()> +<#if TestService.testHasChildren(test)>
    <@recurse_nodes test=test />
    diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/tag.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/tag.ftl index dc3d07e..37db43d 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/tag.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/tag.ftl @@ -59,7 +59,7 @@ - <#list context.testList as test> + <#list context.tests as test>
    @@ -67,7 +67,7 @@
    ${test.startTime?string[("HH:mm:ss a")]} - + ${test.name} <#if test.parent??>
    diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl index 718f1b5..822a967 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/test.ftl @@ -13,7 +13,7 @@ <#include "partials/head.ftl"> <#if offline=="true"> - + <#else> @@ -91,7 +91,7 @@
      <#list report.testList as test> -
    • @@ -101,7 +101,7 @@

      ${test.name}

      -

      ${test.runDuration}

      +

      ${TestService.getRunDuration(test)}

      ${test.startTime?string("HH:mm:ss a")}
      @@ -112,9 +112,9 @@
      ${test.name}
      ${test.startTime?string("MM.dd.yyyy HH:mm:ss")} ${test.endTime?string("MM.dd.yyyy HH:mm:ss")} - ${test.runDuration} + ${TestService.getRunDuration(test)}
    - <#if test.hasAttributes()> + <#if TestService.testHasAttributes(test)>
    <@attributes test=test />
    diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/author-view/v3-html-author-view.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/author-view/v3-html-author-view.ftl index 1d7cce1..0012640 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/author-view/v3-html-author-view.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/author-view/v3-html-author-view.ftl @@ -52,7 +52,7 @@ <#list author.getTestList() as test> ${ test.startTime?datetime?string["${timeStampFormat}"] } - ${ test.hierarchicalName } + ${ test.hierarchicalName } ${ test.status } diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/category-view/v3-html-category-view.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/category-view/v3-html-category-view.ftl index eae1e24..cb3a62c 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/category-view/v3-html-category-view.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/category-view/v3-html-category-view.ftl @@ -49,10 +49,10 @@ - <#list category.getTestList() as test> + <#list category.tests as test> ${ test.startTime?datetime?string["${timeStampFormat}"] } - ${ test.hierarchicalName } + ${ test.name } ${ test.status } diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/exception-view/v3-html-exception-view.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/exception-view/v3-html-exception-view.ftl index b5721e8..ab8c5c6 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/exception-view/v3-html-exception-view.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/exception-view/v3-html-exception-view.ftl @@ -39,7 +39,7 @@ <#if testException.getExceptionName() == exception.exceptionInfo.getExceptionName()> ${ test.startTime?datetime?string["${timeStampFormat}"] } - ${ test.hierarchicalName } + ${ test.hierarchicalName } diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-bdd.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-bdd.ftl index 160064c..c4fd719 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-bdd.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-bdd.ftl @@ -8,20 +8,20 @@
    ${test.description}
    <#list test.nodeContext.all as node> -
    - <#if node.hasCategory()> +
    + <#if TestService.testHasCategory(node)>
    <#list node.categoryContext.all as category> ${category.name}
    - ${node.runDuration} + ${TestService.getRunDuration(node)}
    - <#if node.hasChildren()> + <#if TestService.testHasChildren(node)>
      <#list node.nodeContext.all as child> -
    • +
    • ${MaterialIcon.getIcon(child.status)}${child.name}
      - <#if child.screenCaptureList?? && child.screenCaptureList?size != 0> + <#if TestService.testHasScreenCapture(child)>
        - <#list child.screenCaptureList as sc> + <#list child.screenCaptureContext.all as sc>
      • panorama
      @@ -49,14 +49,14 @@
      ${log.details}
      - <#if child.hasChildren()> + <#if TestService.testHasChildren(child)>
        <#list child.nodeContext.all as gc> -
      • +
      • ${MaterialIcon.getIcon(gc.status)}${gc.name}
        - <#if gc.screenCaptureList?? && gc.screenCaptureList?size != 0> + <#if TestService.testHasScreenCapture(gc)>
          - <#list gc.screenCaptureList as sc> + <#list gc.screenCaptureContext.all as sc>
        • panorama
        diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-standard.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-standard.ftl index 518ebb1..7aa8bfd 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-standard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-standard.ftl @@ -1,28 +1,28 @@
        ${ test.startTime?datetime?string["${timeStampFormat}"] } ${ test.endTime?datetime?string["${timeStampFormat}"] } - ${ test.getRunDuration()?string } + ${ TestService.getRunDuration(test)?string }
        <#if test.description?? && test.description?has_content>
        ${ test.description}
        -<#if test.hasAuthor() || test.hasCategory()> +<#if TestService.testHasAttributes(test)>
        - <#if test.hasCategory()> + <#if TestService.testHasCategory(test)>
        <#list test.categoryContext.all as category> ${ category.name }
        - <#if test.hasAuthor()> + <#if TestService.testHasAuthor(test)>
        <#list test.authorContext.all as author> ${ author.name }
        - <#if test.hasDevice()> + <#if TestService.testHasDevice(test)>
        <#list test.deviceContext.all as device> ${ device.name } @@ -31,7 +31,7 @@
        -<#if test.hasLog()> +<#if TestService.testHasLog(test)>
        @@ -58,7 +58,7 @@ <#else> ${log.details} - <#if log.hasScreenCapture()>${log.screenCaptureContext.last.source} + <#if LogService.logHasScreenCapture(log)>${log.screenCaptureContext.last.source} @@ -66,18 +66,18 @@
        -<#if test.nodeContext?? && test.nodeContext.all?size != 0> +<#if TestService.testHasChildren(test)>
          <#macro recurse_nodes nodeList> <#list nodeList as node> - <#assign leaf=(node.hasChildren())?then('','leaf')> -
        • + <#assign leaf=(TestService.testHasChildren(node))?then('','leaf')> +
        • ${ node.name }
          ${ node.startTime?datetime?string["${timeStampFormat}"] } - · ${ node.runDuration } + · ${ TestService.getRunDuration(node) } ${ node.status } - <#if node.hasCategory()> + <#if TestService.testHasCategory(node)>
          <#list node.categoryContext.all as category> ${ category.name } @@ -89,13 +89,13 @@ <#if node.getStatus()=='pass' && disableToggleActionForPassedNode=='true'> <#assign displayContent=false> - <#if node.hasLog() && displayContent> + <#if TestService.testHasLog(node) && displayContent>
          - <#if node.hasLog()> + <#if TestService.testHasLog(node)> <#if node.description?? && node.description?has_content>
          ${ node.description}
          - <#if node.hasAuthor()> + <#if TestService.testHasAuthor(node)>
          <#list node.authorContext.all as author> ${ author.name } @@ -128,15 +128,15 @@ <#else> ${log.details} - <#if log.hasScreenCapture()>${log.screenCaptureContext.last.source} + <#if LogService.logHasScreenCapture(log)>${log.screenCaptureContext.last.source} - <#if node.screenCaptureList?? && node.screenCaptureList?size != 0> + <#if TestService.testHasScreenCapture(node)>
            - <#list node.screenCaptureList as sc> + <#list node.screenCaptureContext.all as sc>
          • ${ sc.source }
          @@ -145,7 +145,7 @@
          - <#if node.hasChildren()> + <#if TestService.testHasChildren(node)>
            <@recurse_nodes nodeList=node.nodeContext.all />
          diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view.ftl index 1244956..f3b7e3a 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/test-view/v3-html-test-view.ftl @@ -38,7 +38,7 @@
          @@ -337,6 +359,16 @@ infoGrandChild: ${ report.reportStatusStats.grandChildCountInfo?c }, debugGrandChild: ${ report.reportStatusStats.grandChildCountDebug?c }, exceptionsGrandChild: ${ report.reportStatusStats.grandChildCountExceptions?c }, + eventsCount: ${ report.reportStatusStats.eventsCount?c }, + passEvents: ${ report.reportStatusStats.eventsCountPass?c }, + failEvents: ${ report.reportStatusStats.eventsCountFail?c }, + fatalEvents: ${ report.reportStatusStats.eventsCountFatal?c }, + errorEvents: ${ report.reportStatusStats.eventsCountError?c }, + warningEvents: ${ report.reportStatusStats.eventsCountWarning?c }, + skipEvents: ${ report.reportStatusStats.eventsCountSkip?c }, + infoEvents: ${ report.reportStatusStats.eventsCountInfo?c }, + debugEvents: ${ report.reportStatusStats.eventsCountDebug?c }, + exceptionsEvents: ${ report.reportStatusStats.eventsCountExceptions?c } }; <#if config.getConfig("enableTimeline")=='true'> diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/spark.spa.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/spark.spa.ftl index 4316486..e690b83 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/spark.spa.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/spark.spa.ftl @@ -9,16 +9,6 @@ <#assign pageClass="bdd-report" isbdd=true> -<#assign boxsize='col-md-12'> -<#if report.reportStatusStats.childCount!=0> - <#assign boxsize='col-sm-12 col-md-6'> - -<#if (report.analysisStrategy=="BDD") || (report.reportStatusStats.childCount != 0 && report.reportStatusStats.grandChildCount != 0)> - <#assign boxsize='col-sm-12 col-md-4'> - - -<#assign chartWidth="115" chartHeight="90" chartBoxHeight="94"> - <#include "partials/head.ftl"> From 966183e63943c71ac3a608299a55c5eba1bb862e Mon Sep 17 00:00:00 2001 From: anshooarora Date: Wed, 1 Jan 2020 22:10:17 -0800 Subject: [PATCH 43/77] fix js issue with views toggle not referencing .spa class --- .../aventstack/extentreports/offline/spark/js/spark-script.js | 2 +- .../com/aventstack/extentreports/view/spark/partials/head.ftl | 4 ++-- .../aventstack/extentreports/view/spark/partials/scripts.ftl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js index 04bd985..2439ff5 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js @@ -89,7 +89,7 @@ $(document).ready(function() { } // SPA only: hide all views except test on document load - $(".dashboard-view,.tag-view,.exception-view").addClass("d-none"); + $(".spa .dashboard-view,.spa .tag-view,.spa .exception-view").addClass("d-none"); // remove links for spa page // this prevents invalid navigation to external html files diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl index 9b37d05..0994f0b 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl @@ -1,4 +1,4 @@ -<#assign resourceCDN=config.getConfig('resourceCDN') cdnURI="cdn.rawgit.com/extent-framework/extent-github-cdn/" csscommit="4dd3b1c" jscommit="24cb10e" iconcommit="d74480e"> +<#assign resourceCDN=config.getConfig('resourceCDN') cdnURI="cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@" csscommit="ff53917fbbdb5ef820abbbe4d199a6942dc771ff" jscommit="832f979664f9d68bf618db3ac87498ac6c1a6390" iconcommit="ff53917fbbdb5ef820abbbe4d199a6942dc771ff"> <#if resourceCDN=="extentreports"> <#assign cdnURI="extentreports.com/resx" csscommit="" jscommit="" iconcommit=""> @@ -15,7 +15,7 @@ <#else> - + <#include "../../commons/commons-inject-css.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/scripts.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/scripts.ftl index 1fcbec2..755f96a 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/scripts.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/scripts.ftl @@ -1,7 +1,7 @@ <#if offline=="true"> <#else> - + <#if config.containsConfig("js") && config.getConfig("js")?has_content> <#include "../../commons/commons-inject-js.ftl"> From 9927664181e5dbcfb902f862953645e0e21892f6 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 2 Jan 2020 22:25:19 -0800 Subject: [PATCH 44/77] fix view references with TestService, LogService --- .../commons/commons-dashboard-scripts.ftl | 2 +- .../view/commons/commons-macros.ftl | 15 ++++++------ .../view/commons/commons-tag.ftl | 2 +- .../view/logger/logger-dashboard.ftl | 4 ++-- .../view/logger/logger-exception.ftl | 4 ++-- .../extentreports/view/logger/logger-tag.ftl | 4 ++-- .../extentreports/view/logger/logger-test.ftl | 12 +++++----- .../partials/logger-nav-right-items.ftl | 2 +- .../view/logger/partials/logger-nav.ftl | 2 +- .../view/spark/partials/dashboard.ftl | 24 +++++++++---------- 10 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard-scripts.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard-scripts.ftl index b1d2877..f0809e1 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard-scripts.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-dashboard-scripts.ftl @@ -108,7 +108,7 @@ } })(); }) - <#macro listTestNameDuration testList><#if report.testList??><#list report.testList as t>"${t.name}":${(t.runDurationMillis/1000)?c?replace(",","")}<#if t_has_next>, + <#macro listTestNameDuration testList><#if report.testList??><#list report.testList as t>"${t.name}":${(TestService.getRunDurationMillis(t)/1000)?c?replace(",","")}<#if t_has_next>, var timeline = { <@listTestNameDuration testList=report.testList /> }; diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl index a30a9c4..6967e19 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-macros.ftl @@ -1,19 +1,19 @@ <#macro attributes test> - <#if test.hasCategory()> + <#if TestService.testHasCategory(test)> <#list test.categoryContext.all as category> ${category.name} - <#if test.hasAuthor()> + <#if TestService.testHasAuthor(test)> <#list test.authorContext.all as author> ${author.name} - <#if test.hasDevice()> + <#if TestService.testHasDevice(test)> <#list test.deviceContext.all as device> ${device.name} @@ -23,9 +23,8 @@ <#macro media el> - <#if el.hasScreenCapture()> - <#if el.screenCaptureContext??>${el.screenCaptureContext.last.source} - <#else>${el.screenCaptureList[0].source} + <#if el.screenCaptureContext?? && !el.screenCaptureContext.isEmpty()> + ${el.screenCaptureContext.last.source} @@ -33,10 +32,10 @@ <#assign n=test level=n.level> <#if level!=0><#assign n=test.parent><#if n.level!=0><#assign n=n.parent><#if n.level!=0><#assign n=n.parent> - + ${test.status} ${test.name} <#if level!=0>
          ${test.parent.name} - ${test.runDuration}c + ${TestService.getRunDuration(test)}c <@attributes test=test /> <@media el=test /> diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-tag.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-tag.ftl index 397d4f8..f798ff4 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-tag.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-tag.ftl @@ -37,7 +37,7 @@ Source - <#list category.getTestList() as test> + <#list category.tests as test> <@row test=test level=test.level /> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl index 27ac388..c6e22cb 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-dashboard.ftl @@ -25,10 +25,10 @@
          - <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/js/"> + <#assign p="https://cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@832f979664f9d68bf618db3ac87498ac6c1a6390/commons/js/"> <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> + <#if config.containsConfig("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> <#include "../commons/commons-dashboard-scripts.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl index c1bd918..223fc26 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-exception.ftl @@ -47,10 +47,10 @@
    - <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/js/"> + <#assign p="https://cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@832f979664f9d68bf618db3ac87498ac6c1a6390/commons/js/"> <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> + <#if config.containsConfig("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl index 4b34763..ce25a77 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-tag.ftl @@ -55,10 +55,10 @@
    - <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/js/"> + <#assign p="https://cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@832f979664f9d68bf618db3ac87498ac6c1a6390/commons/js/"> <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> + <#if config.containsConfig("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl index e613000..fdf7571 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl @@ -108,28 +108,28 @@ ${log.timestamp?string("MM.dd.yyyy HH:mm:ss")}  ${log.status?replace("ing","")}<#list log.status.toString()?replace("ing","")?length..5 as x>  ${spacer}[${test.name}] - <#if log.hasScreenCapture()>${log.screenCaptureContext.last.sourceWithIcon} + <#if LogService.logHasScreenCapture(log)>${log.screenCaptureContext.last.sourceWithIcon} <#if log.details??>${log.details}<#if log.exceptionInfo??>threw an exception
    <#macro attributes test> - <#if test.hasCategory()> + <#if TestService.testHasCategory(test)> <#list test.categoryContext.all as category> ${category.name} - <#if test.hasAuthor()> + <#if TestService.testHasCategory(test)> <#list test.authorContext.all as author> ${author.name} - <#if test.hasDevice()> + <#if TestService.testHasCategory(test)> <#list test.deviceContext.all as device> ${device.name} @@ -159,10 +159,10 @@ - <#assign p="https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/logger/js/"> + <#assign p="https://cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@832f979664f9d68bf618db3ac87498ac6c1a6390/logger/js/"> <#if offline=="true"><#assign p=config.getConfig("offlineDirectory")> - <#if config.containsKey("scripts") && config.getConfig("scripts")?has_content> + <#if config.containsConfig("scripts") && config.getConfig("scripts")?has_content> <#include "../commons/commons-inject-js.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav-right-items.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav-right-items.ftl index 7b08467..7e0a331 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav-right-items.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav-right-items.ftl @@ -1,3 +1,3 @@ -
  • ${config.getValue("reportName")}
  • +
  • ${config.getConfig("reportName")}
  • ${report.startTime?datetime?string["${timeStampFormat}"]}
  • 4.0
  • diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav.ftl index 35223ba..dc1619f 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-nav.ftl @@ -37,7 +37,7 @@ - <#if config.getValue("enableDashboard")=="true"> + <#if config.getConfig("enableDashboard")=="true">
  • diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl index d783b58..03a4ae7 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl @@ -95,9 +95,9 @@
    -
    -

    ${parentHeading}

    -

    ${report.reportStatusStats.parentCount}

    +
    +
    ${parentHeading}
    +

    ${report.reportStatusStats.parentCount}

    ${report.reportStatusStats.parentPercentagePass?string("#.00")}% @@ -115,9 +115,9 @@
    -
    -

    ${childHeading}

    -

    ${report.reportStatusStats.childCount}

    +
    +
    ${childHeading}
    +

    ${report.reportStatusStats.childCount}

    ${report.reportStatusStats.childPercentagePass?string("#.00")}% @@ -135,9 +135,9 @@
    -
    -

    Start

    -
    ${report.startTime?datetime?string["${timeStampFormat}"]}
    +
    +
    Start
    +

    ${report.startTime?datetime?string["${timeStampFormat}"]}

    @@ -151,9 +151,9 @@
    -
    -

    Duration

    -
    ${report.longRunDuration}
    +
    +
    Duration
    +

    ${report.longRunDuration}

    From 9e3168c3944d454fbf4c673c2a44f16f4e6a0ef5 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 2 Jan 2020 22:25:30 -0800 Subject: [PATCH 45/77] use jsDelivr --- .../view/logger/partials/logger-head.ftl | 12 ++++++------ .../extentreports/view/v3html/v3-html-index.ftl | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-head.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-head.ftl index 703b0a6..84ae5e0 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-head.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/partials/logger-head.ftl @@ -1,6 +1,6 @@ - - ${config.getValue("documentTitle")} + + ${config.getConfig("documentTitle")} @@ -9,13 +9,13 @@ <#if offline=="true"> - - + + <#else> - + - <#if config.containsKey("styles")> + <#if config.containsConfig("styles")> <#include "../../commons/commons-inject-css.ftl"> diff --git a/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl b/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl index aa6ea3b..2848730 100644 --- a/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/v3html/v3-html-index.ftl @@ -33,7 +33,7 @@ <#assign timeStampFormat = config.getConfig('timeStampFormat')> -<#assign resourceCDN=config.getConfig('resourceCDN') cdnURI="cdn.rawgit.com/extent-framework/extent-github-cdn/" csscommit="b65cd69" jscommit="b65cd69"> +<#assign resourceCDN=config.getConfig('resourceCDN') cdnURI="cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@" csscommit="ff53917fbbdb5ef820abbbe4d199a6942dc771ff" jscommit="ff53917fbbdb5ef820abbbe4d199a6942dc771ff"> <#if resourceCDN=="extentreports"> <#assign cdnURI="extentreports.com/resx" csscommit="" jscommit=""> From c6c1e7e52b2c1a9e0bfc4771df8ac088f50fc7c0 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Thu, 2 Jan 2020 22:25:41 -0800 Subject: [PATCH 46/77] minor style update --- .../extentreports/offline/spark/css/spark-style.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css index 581fde8..bb635d8 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css @@ -408,6 +408,14 @@ img.r-img { color: #ff66ff; } +/** + * dashboard + * +**/ +.dashboard-view .media>.card-header { + padding:0 +} + /** * Themes From d355a93bb920ae397463f63c9326bf7ef513c430 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 00:18:36 -0800 Subject: [PATCH 47/77] changing names inline with AbstractStructure context --- .../aventstack/extentreports/ExtentTest.java | 7 +++--- .../extentreports/ReportObservable.java | 24 ++++++++++++------- .../aventstack/extentreports/model/Log.java | 14 +++++------ .../aventstack/extentreports/model/Media.java | 2 +- .../model/service/LogService.java | 2 +- .../view/commons/commons-exception.ftl | 4 ++-- .../view/commons/commons-variables.ftl | 2 +- .../extentreports/view/logger/logger-test.ftl | 2 +- .../view/spark/partials/bdd-content.ftl | 4 ++-- .../view/spark/partials/dashboard.ftl | 6 ++--- .../view/spark/partials/exception.ftl | 6 ++--- .../view/spark/partials/sidenav.ftl | 4 ++-- .../author-view/v3-html-author-view.ftl | 4 ++-- .../exception-view/v3-html-exception-view.ftl | 10 ++++---- 14 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentTest.java b/src/main/java/com/aventstack/extentreports/ExtentTest.java index 408d47d..b97318f 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentTest.java +++ b/src/main/java/com/aventstack/extentreports/ExtentTest.java @@ -315,7 +315,7 @@ private void addMedia(Log evt, MediaEntityModelProvider provider) { if (clazz.equals(ScreenCapture.class)) { ScreenCapture c = (ScreenCapture) provider.getMedia(); - evt.getScreenCapture().add(c); + evt.getScreenCaptureContext().add(c); } else { } @@ -358,9 +358,9 @@ private ExtentTest addLog(Log evt) { getModel().end(); extent.addLog(getModel(), evt); - if (!evt.getScreenCapture().isEmpty()) { + if (!evt.getScreenCaptureContext().isEmpty()) { try { - extent.addScreenCapture(evt, evt.getScreenCapture().getLast()); + extent.addScreenCapture(evt, evt.getScreenCaptureContext().getLast()); } catch (IOException e) { e.printStackTrace(); } @@ -408,6 +408,7 @@ public ExtentTest log(Status status, Throwable t, MediaEntityModelProvider provi exceptionInfo.setStackTrace(ExceptionUtil.getStackTrace(t)); Log evt = createLog(status); evt.setExceptionInfo(exceptionInfo); + getModel().getExceptionInfoContext().add(exceptionInfo); addMedia(evt, provider); return addLog(evt); } diff --git a/src/main/java/com/aventstack/extentreports/ReportObservable.java b/src/main/java/com/aventstack/extentreports/ReportObservable.java index 878c892..94c6ca3 100644 --- a/src/main/java/com/aventstack/extentreports/ReportObservable.java +++ b/src/main/java/com/aventstack/extentreports/ReportObservable.java @@ -95,7 +95,7 @@ abstract class ReportObservable implements ReportService { /** * A collection of tests arranged by exception */ - private ExceptionTestContextStore exceptionContextBuilder = new ExceptionTestContextStore(); + private ExceptionTestContextStore exceptionContext = new ExceptionTestContextStore(); /** * A context of all system or environment variables @@ -441,7 +441,7 @@ public synchronized void generateRecentStatus() { test.getDeviceContext().getAll().forEach(x -> deviceContext.setAttributeContext((Device) x, test)); } if (TestService.testHasException(test)) { - test.getExceptionInfoContext().getAll().forEach(x -> exceptionContextBuilder.setExceptionContext(x, test)); + test.getExceptionInfoContext().getAll().forEach(x -> exceptionContext.setExceptionContext(x, test)); } if (TestService.testHasChildren(test)) { for (Test node : test.getNodeContext().getAll()) { @@ -484,7 +484,7 @@ private void copyNodeAttributeAndRunTimeInfoToAttributeContexts(Test node) { node.getDeviceContext().getAll().forEach(x -> deviceContext.setAttributeContext((Device) x, node)); } if (TestService.testHasException(node)) { - node.getExceptionInfoContext().getAll().forEach(x -> exceptionContextBuilder.setExceptionContext(x, node)); + node.getExceptionInfoContext().getAll().forEach(x -> exceptionContext.setExceptionContext(x, node)); } if (TestService.testHasChildren(node)) { node.getNodeContext().getAll().forEach(this::copyNodeAttributeAndRunTimeInfoToAttributeContexts); @@ -498,11 +498,19 @@ private synchronized void notifyReporters() { if (!testList.isEmpty() && TestService.isTestBehaviorDriven(testList.get(0))) { strategy = AnalysisStrategy.BDD; } - ReportAggregates reportAggregates = new ReportAggregatesBuilder().setAuthorContext(authorContext) - .setCategoryContext(categoryContext).setDeviceContext(deviceContext) - .setExceptionContext(exceptionContextBuilder).setReportStatusStats(stats).setStatusCollection(statusSet) - .setSystemAttributeContext(systemAttributeContext).setTestList(testList) - .setTestRunnerLogs(testRunnerLogs).setStartTime(reportStartDate).setEndTime(reportEndDate).build(); + ReportAggregates reportAggregates = new ReportAggregatesBuilder() + .setAuthorContext(authorContext) + .setCategoryContext(categoryContext) + .setDeviceContext(deviceContext) + .setExceptionContext(exceptionContext) + .setReportStatusStats(stats) + .setStatusCollection(statusSet) + .setSystemAttributeContext(systemAttributeContext) + .setTestList(testList) + .setTestRunnerLogs(testRunnerLogs) + .setStartTime(reportStartDate) + .setEndTime(reportEndDate) + .build(); reporterList.forEach(x -> x.setAnalysisStrategy(strategy)); reporterList.forEach(x -> x.flush(reportAggregates)); } diff --git a/src/main/java/com/aventstack/extentreports/model/Log.java b/src/main/java/com/aventstack/extentreports/model/Log.java index 7ebb249..0b5084a 100644 --- a/src/main/java/com/aventstack/extentreports/model/Log.java +++ b/src/main/java/com/aventstack/extentreports/model/Log.java @@ -13,7 +13,7 @@ public class Log implements Serializable, RunResult { private Date timestamp = Calendar.getInstance().getTime(); private ExceptionInfo exceptionInfo; - private AbstractStructure screenCapture; + private AbstractStructure screenCaptureContext; private transient Test test; private Status status; private String details; @@ -39,15 +39,15 @@ public void setExceptionInfo(ExceptionInfo exceptionInfo) { this.exceptionInfo = exceptionInfo; } - public AbstractStructure getScreenCapture() { - if (screenCapture == null) { - screenCapture = new AbstractStructure<>(); + public AbstractStructure getScreenCaptureContext() { + if (screenCaptureContext == null) { + screenCaptureContext = new AbstractStructure<>(); } - return screenCapture; + return screenCaptureContext; } - public void setScreenCapture(AbstractStructure screenCapture) { - this.screenCapture = screenCapture; + public void setScreenCaptureContext(AbstractStructure screenCapture) { + this.screenCaptureContext = screenCapture; } public Test getTest() { diff --git a/src/main/java/com/aventstack/extentreports/model/Media.java b/src/main/java/com/aventstack/extentreports/model/Media.java index 6988aaf..67c641b 100644 --- a/src/main/java/com/aventstack/extentreports/model/Media.java +++ b/src/main/java/com/aventstack/extentreports/model/Media.java @@ -9,7 +9,7 @@ public class Media implements Serializable { private static final long serialVersionUID = 2620739620884939951L; - private String name; + private String name = ""; private String description; private String path; private int sequence; diff --git a/src/main/java/com/aventstack/extentreports/model/service/LogService.java b/src/main/java/com/aventstack/extentreports/model/service/LogService.java index dfb7b2f..daf9f53 100644 --- a/src/main/java/com/aventstack/extentreports/model/service/LogService.java +++ b/src/main/java/com/aventstack/extentreports/model/service/LogService.java @@ -5,7 +5,7 @@ public class LogService { public static Boolean logHasScreenCapture(Log log) { - return !log.getScreenCapture().isEmpty(); + return !log.getScreenCaptureContext().isEmpty(); } } diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-exception.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-exception.ftl index e91e490..694828f 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-exception.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-exception.ftl @@ -18,7 +18,7 @@
    ${exception.exceptionInfo.exceptionName}
    - ${exception.testList?size} tests + ${exception.tests?size} tests
    ${exception.exceptionInfo.exceptionName}
    @@ -32,7 +32,7 @@ Source - <#list exception.getTestList() as test> + <#list exception.tests as test> <@row test=test level=test.level /> diff --git a/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl b/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl index ea7d130..c0ffa55 100644 --- a/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/commons/commons-variables.ftl @@ -7,7 +7,7 @@ <#assign categoryContext=report.getCategoryContextInfo().getTestAttributeTestContext()> <#assign authorContext=report.getAuthorContextInfo().getTestAttributeTestContext()> <#assign deviceContext=report.getDeviceContextInfo().getTestAttributeTestContext()> -<#assign exceptionContext=report.getExceptionContextInfo().getExceptionTestContext()> +<#assign exceptionContext=report.exceptionContextInfo.exceptionTestContext> <#assign reportType="" parentHeading="Tests" childHeading="Steps" grandChildHeading="" size=2> <#if report.analysisStrategy=="SUITE"> diff --git a/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl b/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl index fdf7571..fde08aa 100644 --- a/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/logger/logger-test.ftl @@ -108,7 +108,7 @@ ${log.timestamp?string("MM.dd.yyyy HH:mm:ss")}  ${log.status?replace("ing","")}<#list log.status.toString()?replace("ing","")?length..5 as x>  ${spacer}[${test.name}] - <#if LogService.logHasScreenCapture(log)>${log.screenCaptureContext.last.sourceWithIcon} + <#if LogService.logHasScreenCapture(log)>${log.screenCaptureContext.last.source} <#if log.details??>${log.details}<#if log.exceptionInfo??>threw an exception
    diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/bdd-content.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/bdd-content.ftl index 49a6924..84eb489 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/bdd-content.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/bdd-content.ftl @@ -26,7 +26,7 @@
    <#if TestService.testHasChildren(node)> - <#if node.bddType.toString()=="Scenario Outline"> + <#if node.bddType?? && node.behaviorDrivenTypeName=="Scenario Outline">
    <#list node.nodeContext.all as child>
    @@ -56,7 +56,7 @@
    <#list node.nodeContext.all as child> -
    +
    diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl index 03a4ae7..3bde40c 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/dashboard.ftl @@ -17,7 +17,7 @@
    ${report.reportStatusStats.parentCountFail + report.reportStatusStats.parentCountFatal} ${parentHeading?lower_case} failed, - ${report.reportStatusStats.parentCountError + report.reportStatusStats.parentCountWarning + report.reportStatusStats.parentCountSkip} others + ${report.reportStatusStats.parentCountSkip} skipped, ${report.reportStatusStats.parentCountError + report.reportStatusStats.parentCountWarning} others
    @@ -38,7 +38,7 @@
    ${report.reportStatusStats.childCountPass} ${childHeading?lower_case} passed
    ${report.reportStatusStats.childCountFail + report.reportStatusStats.childCountFatal} ${childHeading?lower_case} failed, - ${report.reportStatusStats.childCountError + report.reportStatusStats.childCountWarning + report.reportStatusStats.childCountSkip + report.reportStatusStats.childCountInfo} others + ${report.reportStatusStats.childCountSkip} skipped, ${report.reportStatusStats.childCountError + report.reportStatusStats.childCountWarning + report.reportStatusStats.childCountInfo} others
    @@ -60,7 +60,7 @@
    ${report.reportStatusStats.grandChildCountPass} ${grandChildHeading?lower_case} passed
    ${report.reportStatusStats.grandChildCountFail + report.reportStatusStats.grandChildCountFatal} ${grandChildHeading?lower_case} failed, - ${report.reportStatusStats.grandChildCountError + report.reportStatusStats.grandChildCountWarning + report.reportStatusStats.grandChildCountSkip + report.reportStatusStats.grandChildCountInfo} others + ${report.reportStatusStats.grandChildCountSkip} skipped, ${report.reportStatusStats.grandChildCountError + report.reportStatusStats.grandChildCountWarning + report.reportStatusStats.grandChildCountInfo} others
    diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/exception.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/exception.ftl index e7ceaa9..3936249 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/exception.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/exception.ftl @@ -23,7 +23,7 @@

    ${context.exceptionInfo.exceptionName}

    -

    ${context.testList?size} tests

    +

    ${context.tests?size} tests

    @@ -39,7 +39,7 @@ - <#list context.testList as test> + <#list context.tests as test>
    @@ -47,7 +47,7 @@
    ${test.startTime?string[("HH:mm:ss a")]} - + ${test.name} <#if test.parent??>
    diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/sidenav.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/sidenav.ftl index fbd7e6c..38d2343 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/sidenav.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/sidenav.ftl @@ -9,7 +9,7 @@ Tests
  • - <#if categoryContext?? && categoryContext?size != 0> + <#if categoryContext?has_content> - <#if exceptionContext?? && exceptionContext?size != 0> + <#if exceptionContext?has_content>
  • ${ exception.exceptionInfo.getExceptionName() } - ${ exception.testList?size } + ${ exception.tests?size }
    @@ -34,14 +34,14 @@ - <#list exception.getTestList() as test> - <#list test.getExceptionInfoList() as testException> + <#list exception.tests as test> + <#list test.exceptionInfoContext.all as testException> <#if testException.getExceptionName() == exception.exceptionInfo.getExceptionName()> ${ test.startTime?datetime?string["${timeStampFormat}"] } - ${ test.hierarchicalName } + ${ test.name } - + From b7b62c32dd5b9b429ac6e9aedda0eef108a5f2e2 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 00:18:51 -0800 Subject: [PATCH 48/77] adds getSource() --- .../com/aventstack/extentreports/model/ScreenCapture.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java index 40c6df8..fffd628 100644 --- a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java +++ b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java @@ -20,4 +20,11 @@ public String getScreenCapturePath() { public Boolean isBase64() { return getBase64String() != null; } + + public String getSource() { + if (getBase64String() != null) + return "base64-img"; + return ""; + } + } From 1ef547aacc96aac472ec2420d3f9b5fb3cfb4f02 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 13:01:40 -0800 Subject: [PATCH 49/77] adds ExtentKlovReporter --- .../aventstack/extentreports/model/Log.java | 15 +- .../aventstack/extentreports/model/Test.java | 19 +- .../reporter/ExtentKlovReporter.java | 695 ++++++++++++++++++ .../extentreports/utils/IntUtil.java | 17 + 4 files changed, 744 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/utils/IntUtil.java diff --git a/src/main/java/com/aventstack/extentreports/model/Log.java b/src/main/java/com/aventstack/extentreports/model/Log.java index 0b5084a..3532094 100644 --- a/src/main/java/com/aventstack/extentreports/model/Log.java +++ b/src/main/java/com/aventstack/extentreports/model/Log.java @@ -4,10 +4,12 @@ import java.util.Calendar; import java.util.Date; +import org.bson.types.ObjectId; + import com.aventstack.extentreports.RunResult; import com.aventstack.extentreports.Status; -public class Log implements Serializable, RunResult { +public class Log implements Serializable, RunResult, BasicMongoReportElement { private static final long serialVersionUID = 8072065800800347981L; private Date timestamp = Calendar.getInstance().getTime(); @@ -18,6 +20,7 @@ public class Log implements Serializable, RunResult { private Status status; private String details; private int sequence; + private ObjectId objectId; public Log(Test test) { this.test = test; @@ -81,5 +84,15 @@ public int getSequence() { public void setSequence(int sequence) { this.sequence = sequence; } + + @Override + public ObjectId getObjectId() { + return objectId; + } + + @Override + public void setObjectId(ObjectId id) { + this.objectId = id; + } } diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index d89e200..f0fb804 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -6,13 +6,15 @@ import java.util.Date; import java.util.concurrent.atomic.AtomicInteger; +import org.bson.types.ObjectId; + import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.RunResult; import com.aventstack.extentreports.Status; import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel; import com.google.gson.annotations.Expose; -public class Test implements Serializable, RunResult { +public class Test implements Serializable, RunResult, BasicMongoReportElement { private static final long serialVersionUID = -8681630689550647312L; private static final AtomicInteger atomicInt = new AtomicInteger(0); @@ -34,6 +36,11 @@ public class Test implements Serializable, RunResult { * A unique ID, generated by AtomicInteger */ private transient int id = atomicInt.incrementAndGet(); + + /** + * An assigned {@link ObjectId} + */ + private ObjectId objectId; /** * If this Test is at the top-most level, or in other words, has a level value @@ -362,4 +369,14 @@ public Boolean isBehaviorDrivenType() { return getBddType() != null; } + @Override + public ObjectId getObjectId() { + return objectId; + } + + @Override + public void setObjectId(ObjectId id) { + this.objectId = id; + } + } diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java new file mode 100644 index 0000000..8431620 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -0,0 +1,695 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import org.bson.Document; +import org.bson.types.ObjectId; + +import com.aventstack.extentreports.ReportAggregates; +import com.aventstack.extentreports.ReportStatusStats; +import com.aventstack.extentreports.Status; +import com.aventstack.extentreports.mediastorage.KlovMediaStorageHandler; +import com.aventstack.extentreports.mediastorage.model.KlovMedia; +import com.aventstack.extentreports.model.Attribute; +import com.aventstack.extentreports.model.Author; +import com.aventstack.extentreports.model.BasicMongoReportElement; +import com.aventstack.extentreports.model.Category; +import com.aventstack.extentreports.model.Device; +import com.aventstack.extentreports.model.ExceptionInfo; +import com.aventstack.extentreports.model.Log; +import com.aventstack.extentreports.model.ScreenCapture; +import com.aventstack.extentreports.model.SystemAttribute; +import com.aventstack.extentreports.model.Test; +import com.aventstack.extentreports.model.context.SystemAttributeContext; +import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; +import com.aventstack.extentreports.model.service.LogService; +import com.aventstack.extentreports.model.service.TestService; +import com.aventstack.extentreports.utils.IntUtil; +import com.aventstack.extentreports.utils.MongoUtil; +import com.mongodb.MongoClient; +import com.mongodb.MongoClientOptions; +import com.mongodb.MongoClientURI; +import com.mongodb.MongoCredential; +import com.mongodb.ServerAddress; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; + +/** + * ExtentKlovReporter is a NoSQL database reporter (MongoDB), which updates + * information in the database which is then used by the ExtentX server to + * display in-depth analysis. + */ +public class ExtentKlovReporter extends ConfigurableReporter { + + private static final String DEFAULT_PROJECT_NAME_PROP = "klov.project.name"; + private static final String DEFAULT_REPORT_NAME_PROP = "klov.report.name"; + private static final String DEFAULT_MONGODB_HOST_PROP = "mongodb.host"; + private static final String DEFAULT_MONGODB_PORT_PROP = "mongodb.port"; + private static final String DEFAULT_MONGODB_URI_PROP = "mongodb.uri"; + private static final String DEFAULT_KLOV_HOST_PROP = "klov.host"; + private static final String DEFAULT_KLOV_PORT_PROP = "klov.port"; + private static final String REPORTER_NAME = "klov"; + private static final String DB_NAME = "klov"; + private static final String DEFAULT_PROJECT_NAME = "Default"; + + private String url; + private List testList; + private ReportStatusStats stats; + private SystemAttributeContext systemAttributeContext; + private TestAttributeTestContextStore categoryContext; + private TestAttributeTestContextStore authorContext; + private TestAttributeTestContextStore deviceContext; + private Map categoryNameObjectIdCollection = new HashMap<>(); + private Map authorNameObjectIdCollection = new HashMap<>(); + private Map deviceNameObjectIdCollection = new HashMap<>(); + private Map exceptionNameObjectIdCollection = new HashMap<>(); + private ObjectId reportId; + private String reportName; + private ObjectId projectId; + private String projectName; + private MongoClient mongoClient; + private MongoCollection projectCollection; + private MongoCollection reportCollection; + private MongoCollection testCollection; + private MongoCollection logCollection; + private MongoCollection exceptionCollection; + private MongoCollection mediaCollection; + private MongoCollection categoryCollection; + private MongoCollection authorCollection; + private MongoCollection deviceCollection; + private MongoCollection environmentCollection; + private KlovMediaStorageHandler mediaStorageHandler; + + static { + /* use mongodb reporting for only critical/severe events */ + Logger mongoLogger = Logger.getLogger("org.mongodb.driver"); + mongoLogger.setLevel(Level.SEVERE); + } + + /** + * Initializes the KlovReporter + */ + public ExtentKlovReporter() { + } + + /** + * Initializes the KlovReporter with project and report names + * + * @param projectName Name of the project + * @param reportName Name of the report + */ + public ExtentKlovReporter(String projectName, String reportName) { + this.projectName = projectName; + this.reportName = reportName; + } + + /** + * Sets the project name + * + * @param projectName Name of the project + */ + public ExtentKlovReporter setProjectName(String projectName) { + this.projectName = projectName; + return this; + } + + /** + * Sets the report name + * + * @param reportName Name of the report + */ + public ExtentKlovReporter setReportName(String reportName) { + this.reportName = reportName; + return this; + } + + /** + * Initialize Mongo DB connection with host and default port: 27017 + * + * @param host host name + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(String host) { + mongoClient = new MongoClient(host, 27017); + return this; + } + + /** + * Initialize Mongo DB connection with host and {@link MongoClientOptions} + * + * @param host host name + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(String host, MongoClientOptions options) { + mongoClient = new MongoClient(host, options); + return this; + } + + /** + * Initialize Mongo DB connection with host and post + * + * @param host host name + * @param port port number + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(String host, int port) { + mongoClient = new MongoClient(host, port); + return this; + } + + /** + * Initialize Mongo DB connection with a {@link MongoClientURI} + * + * @param uri {@link MongoClientURI} uri + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(MongoClientURI uri) { + mongoClient = new MongoClient(uri); + return this; + } + + /** + * Initializes the Mongo DB connection with {@link ServerAddress} + * + * @param addr {@link ServerAddress} server address + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr) { + mongoClient = new MongoClient(addr); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress} + * addresses + * + * @param seeds A list of {@link ServerAddress} server addresses + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds) { + mongoClient = new MongoClient(seeds); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress} and + * {@link MongoCredential} + * + * @param seeds A list of {@link ServerAddress} server addresses + * @param credentialsList A list of {@link MongoCredential} credentials + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList) { + mongoClient = new MongoClient(seeds, credentialsList); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress}, + * {@link MongoCredential} and {@link MongoClientOptions} + * + * @param seeds A list of {@link ServerAddress} server addresses + * @param credentialsList A list of {@link MongoCredential} credentials + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList, + MongoClientOptions options) { + mongoClient = new MongoClient(seeds, credentialsList, options); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress} and + * {@link MongoClientOptions} + * + * @param seeds A list of {@link ServerAddress} server addresses + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(List seeds, MongoClientOptions options) { + mongoClient = new MongoClient(seeds, options); + return this; + } + + /** + * Initializes the Mongo DB connection with {@link ServerAddress} and a list of + * {@link MongoCredential} credentials + * + * @param addr {@link ServerAddress} server address + * @param credentialsList A list of {@link MongoCredential} credentials + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList) { + mongoClient = new MongoClient(addr, credentialsList); + return this; + } + + /** + * Initializes the Mongo DB connection with a list of {@link ServerAddress}, + * {@link MongoCredential} and {@link MongoClientOptions} + * + * @param addr A list of {@link ServerAddress} server addresses + * @param credentialsList A list of {@link MongoCredential} credentials + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList, + MongoClientOptions options) { + mongoClient = new MongoClient(addr, credentialsList, options); + return this; + } + + /** + * Initializes the Mongo DB connection with a {@link ServerAddress} and + * {@link MongoClientOptions} + * + * @param addr A list of {@link ServerAddress} server addresses + * @param options {@link MongoClientOptions} options + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, MongoClientOptions options) { + mongoClient = new MongoClient(addr, options); + return this; + } + + /** + * Initializes the Mongo DB connection with a connection url + * + * @param url Url string + * @return a {@link ExtentKlovReporter} object + */ + public ExtentKlovReporter initKlovServerConnection(String url) { + this.url = url; + return this; + } + + public void loadInitializationParams(String propertiesPath) throws FileNotFoundException { + File f = new File(propertiesPath); + InputStream stream = new FileInputStream(f); + loadConfig(stream); + loadInitializationParams(); + } + + public void loadInitializationParams(Properties props) { + loadConfig(props); + loadInitializationParams(); + } + + private void loadInitializationParams() { + + String mongoUri = getConfigValue(DEFAULT_MONGODB_URI_PROP); + if (mongoUri == null || mongoUri.isEmpty()) { + String mongoHost = getConfigValue(DEFAULT_MONGODB_HOST_PROP); + String mongoPort = getConfigValue(DEFAULT_MONGODB_PORT_PROP); + int mongoPortInt = IntUtil.tryParseInt(mongoPort) == true ? Integer.valueOf(mongoPort) : -1; + if (mongoHost != null && mongoPortInt != -1) { + initMongoDbConnection(mongoHost, mongoPortInt); + } else if (mongoHost != null) { + initMongoDbConnection(mongoHost); + } + } else { + initMongoDbConnection(new MongoClientURI(mongoUri)); + } + + String projectName = System.getProperty(DEFAULT_PROJECT_NAME_PROP); + projectName = projectName == null || projectName.isEmpty() ? getConfigValue(DEFAULT_PROJECT_NAME_PROP) + : projectName; + this.projectName = projectName == null || projectName.isEmpty() ? this.projectName : projectName; + + String reportName = System.getProperty(DEFAULT_REPORT_NAME_PROP); + reportName = reportName == null || reportName.isEmpty() ? getConfigValue(DEFAULT_REPORT_NAME_PROP) : reportName; + this.reportName = reportName == null || reportName.isEmpty() ? this.reportName : reportName; + + String klovHost = getConfigValue(DEFAULT_KLOV_HOST_PROP); + String klovPort = getConfigValue(DEFAULT_KLOV_PORT_PROP); + + if (klovHost != null && klovPort != null) { + String uri = klovHost + ":" + klovPort; + initKlovServerConnection(uri); + } else if (klovHost != null) { + initKlovServerConnection(klovHost); + } else { + } + } + + private String getConfigValue(String key) { + return String.valueOf(getConfigurationStore().getConfig(key)); + } + + @Override + public void start() { + MongoDatabase db = mongoClient.getDatabase(DB_NAME); + initCollections(db); + setupProject(); + } + + private void initCollections(MongoDatabase db) { + projectCollection = db.getCollection("project"); + reportCollection = db.getCollection("report"); + testCollection = db.getCollection("test"); + logCollection = db.getCollection("log"); + exceptionCollection = db.getCollection("exception"); + mediaCollection = db.getCollection("media"); + categoryCollection = db.getCollection("category"); + authorCollection = db.getCollection("author"); + deviceCollection = db.getCollection("device"); + environmentCollection = db.getCollection("environment"); + } + + private void setupProject() { + String projectName = this.projectName == null || this.projectName.isEmpty() ? DEFAULT_PROJECT_NAME + : this.projectName; + + Document doc = new Document("name", projectName); + Document project = projectCollection.find(doc).first(); + + if (project != null) { + projectId = project.getObjectId("_id"); + } else { + doc.append("createdAt", Calendar.getInstance().getTime()); + projectCollection.insertOne(doc); + projectId = MongoUtil.getId(doc); + } + + setupReport(projectName); + } + + private void setupReport(String projectName) { + String reportName = this.reportName == null || this.reportName.isEmpty() + ? "Build " + Calendar.getInstance().getTimeInMillis() + : this.reportName; + + Document doc = new Document("name", reportName).append("startTime", getStartTime()).append("project", projectId) + .append("projectName", projectName); + + reportCollection.insertOne(doc); + reportId = MongoUtil.getId(doc); + } + + @Override + public void stop() { + mongoClient.close(); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + setEndTime(Calendar.getInstance().getTime()); + this.testList = reportAggregates.getTestList(); + + if (testList == null || testList.isEmpty()) { + return; + } + + this.authorContext = reportAggregates.getAuthorContext(); + this.categoryContext = reportAggregates.getCategoryContext(); + this.deviceContext = reportAggregates.getDeviceContext(); + this.stats = reportAggregates.getReportStatusStats(); + this.systemAttributeContext = reportAggregates.getSystemAttributeContext(); + + Status buildStatus = reportAggregates.getStatus(); + + Document doc = new Document("endTime", getEndTime()).append("duration", getRunDuration()) + .append("status", String.valueOf(buildStatus)).append("parentLength", stats.getParentCount()) + .append("passParentLength", stats.getParentCountPass()) + .append("failParentLength", stats.getParentCountFail()) + .append("fatalParentLength", stats.getParentCountFatal()) + .append("errorParentLength", stats.getParentCountError()) + .append("warningParentLength", stats.getParentCountWarning()) + .append("skipParentLength", stats.getParentCountSkip()) + .append("exceptionsParentLength", stats.getParentCountExceptions()) + .append("childLength", stats.getChildCount()).append("passChildLength", stats.getChildCountPass()) + .append("failChildLength", stats.getChildCountFail()) + .append("fatalChildLength", stats.getChildCountFatal()) + .append("errorChildLength", stats.getChildCountError()) + .append("warningChildLength", stats.getChildCountWarning()) + .append("skipChildLength", stats.getChildCountSkip()) + .append("infoChildLength", stats.getChildCountInfo()) + .append("exceptionsChildLength", stats.getChildCountExceptions()) + .append("grandChildLength", stats.getGrandChildCount()) + .append("passGrandChildLength", stats.getGrandChildCountPass()) + .append("failGrandChildLength", stats.getGrandChildCountFail()) + .append("fatalGrandChildLength", stats.getGrandChildCountFatal()) + .append("errorGrandChildLength", stats.getGrandChildCountError()) + .append("warningGrandChildLength", stats.getGrandChildCountWarning()) + .append("skipGrandChildLength", stats.getGrandChildCountSkip()) + .append("exceptionsGrandChildLength", stats.getGrandChildCountExceptions()) + .append("analysisStrategy", String.valueOf(getAnalysisStrategy())); + + reportCollection.updateOne(new Document("_id", reportId), new Document("$set", doc)); + + insertUpdateSystemAttribute(); + } + + public List getCollectionValues(Map collection) { + if (collection == null || collection.isEmpty()) + return null; + return collection.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList()); + } + + private void insertUpdateSystemAttribute() { + List systemAttrList = systemAttributeContext.getSystemAttributeList(); + Document doc; + + for (SystemAttribute attr : systemAttrList) { + doc = new Document("project", projectId) + .append("report", reportId) + .append("name", attr.getName()); + + Document envSingle = environmentCollection.find(doc).first(); + + if (envSingle == null) { + doc.append("value", attr.getValue()); + environmentCollection.insertOne(doc); + } else { + ObjectId id = envSingle.getObjectId("_id"); + doc = new Document("_id", id).append("value", attr.getValue()); + environmentCollection.updateOne(new Document("_id", id), new Document("$set", doc)); + } + } + } + + @Override + public void onTestStarted(Test test) { + onTestStartedHelper(test); + } + + @Override + public synchronized void onNodeStarted(Test node) { + onTestStartedHelper(node); + } + + private void onTestStartedHelper(Test test) { + Document doc = new Document("project", projectId) + .append("report", reportId) + .append("reportName", reportName) + .append("level", test.getLevel()) + .append("name", test.getName()) + .append("status", test.getStatus().toString()) + .append("description", test.getDescription()) + .append("startTime", test.getStartTime()) + .append("endTime", test.getEndTime()) + .append("bdd", test.isBehaviorDrivenType()) + .append("leaf", test.getNodeContext().isEmpty()) + .append("childNodesLength", test.getNodeContext().size()); + + if (test.isBehaviorDrivenType()) { + doc.append("bddType", test.getBehaviorDrivenTypeName()); + } + + if (test.getParent() != null) { + doc.append("parent", test.getParent().getObjectId()) + .append("parentName", test.getParent().getName()); + updateTestChildrenCount(test.getParent()); + updateTestDesc(test.getParent()); + } + + testCollection.insertOne(doc); + ObjectId testId = MongoUtil.getId(doc); + test.setObjectId(testId); + } + + private void updateTestDesc(Test test) { + Document doc = new Document("description", test.getDescription()); + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + } + + private void updateTestChildrenCount(Test test) { + Document doc = new Document("childNodesLength", test.getNodeContext().size()); + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + } + + @Override + public synchronized void onLogAdded(Test test, Log log) { + Document doc = new Document("test", test.getObjectId()) + .append("project", projectId) + .append("report", reportId) + .append("testName", test.getName()) + .append("sequence", log.getSequence()) + .append("status", log.getStatus().toString()) + .append("timestamp", log.getTimestamp()) + .append("details", log.getDetails()); + + if (log.getExceptionInfo() != null) { + doc.append("exception", log.getExceptionInfo().getExceptionName()).append("stacktrace", + log.getExceptionInfo().getStackTrace()); + } + + if (LogService.logHasScreenCapture(log) && log.getScreenCaptureContext().getFirst().isBase64()) { + doc.append("details", log.getDetails() + log.getScreenCaptureContext().getFirst().getSource()); + } + + logCollection.insertOne(doc); + + ObjectId logId = MongoUtil.getId(doc); + log.setObjectId(logId); + + // check for exceptions.. + if (TestService.testHasException(test)) { + if (exceptionNameObjectIdCollection == null) + exceptionNameObjectIdCollection = new HashMap<>(); + + ExceptionInfo ex = test.getExceptionInfoContext().get(0); + + ObjectId exceptionId; + doc = new Document("report", reportId).append("project", projectId).append("name", ex.getExceptionName()); + + FindIterable iterable = exceptionCollection.find(doc); + Document docException = iterable.first(); + + // check if a matching exception name is available in 'Exception' collection + // (MongoDB) + // if a matching exception name is found, associate with this exception's + // ObjectId + if (!exceptionNameObjectIdCollection.containsKey(ex.getExceptionName())) { + if (docException != null) { + exceptionNameObjectIdCollection.put(ex.getExceptionName(), docException.getObjectId("_id")); + } else { + doc = new Document("project", projectId) + .append("report", reportId) + .append("name", ex.getExceptionName()) + .append("stacktrace", ex.getStackTrace()) + .append("testCount", 0); + + exceptionCollection.insertOne(doc); + + exceptionId = MongoUtil.getId(doc); + docException = exceptionCollection.find(new Document("_id", exceptionId)).first(); + + exceptionNameObjectIdCollection.put(ex.getExceptionName(), exceptionId); + } + } + + Integer testCount = ((Integer) (docException.get("testCount"))) + 1; + doc = new Document("testCount", testCount); + + exceptionCollection.updateOne(new Document("_id", docException.getObjectId("_id")), + new Document("$set", doc)); + + doc = new Document("exception", exceptionNameObjectIdCollection.get(ex.getExceptionName())); + + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + updateTestDesc(test); + } + + endTestRecursive(test); + } + + private void endTestRecursive(Test test) { + Document doc = new Document("status", test.getStatus().toString()).append("endTime", test.getEndTime()) + .append("duration", TestService.getRunDurationMillis(test)) + .append("leaf", test.getNodeContext().isEmpty()) + .append("childNodesLength", test.getNodeContext().size()) + .append("categorized", TestService.testHasCategory(test)) + .append("description", test.getDescription()); + + testCollection.updateOne(new Document("_id", test.getObjectId()), new Document("$set", doc)); + + if (test.getLevel() > 0) { + endTestRecursive(test.getParent()); + } + } + + public void assignAttribute(Test test, Attribute attribute, + Map nameObjectIdCollection, MongoCollection mongoCollection, + TestAttributeTestContextStore attributeContext) { + } + + @Override + public void onCategoryAssigned(Test test, Category category) { + assignAttribute(test, category, categoryNameObjectIdCollection, categoryCollection, categoryContext); + } + + @Override + public void onAuthorAssigned(Test test, Author author) { + assignAttribute(test, author, authorNameObjectIdCollection, authorCollection, authorContext); + } + + @Override + public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { + screenCapture.getBsonId().put("testId", test.getObjectId()); + saveScreenCapture(test, screenCapture); + } + + @Override + public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IOException { + screenCapture.getBsonId().put("logId", log.getObjectId()); + screenCapture.getBsonId().put("testId", log.getTest().getObjectId()); + saveScreenCapture(log, screenCapture); + } + + private void saveScreenCapture(BasicMongoReportElement el, ScreenCapture screenCapture) throws IOException { + if (mediaStorageHandler == null) { + KlovMedia klovMedia = new KlovMedia(projectId, reportId, mediaCollection); + mediaStorageHandler = new KlovMediaStorageHandler(url, klovMedia); + } + mediaStorageHandler.saveScreenCapture(el, screenCapture); + } + + /** + * Returns the active Project ID + * + * @return A {@link ObjectId} object + */ + public ObjectId getProjectId() { + return projectId; + } + + /** + * Returns the active Report ID + * + * @return A {@link ObjectId} object + */ + public ObjectId getReportId() { + return reportId; + } + + @Override + public void onTestRemoved(Test test) { + } + + @Override + public void onDeviceAssigned(Test test, Device device) { + assignAttribute(test, device, deviceNameObjectIdCollection, deviceCollection, deviceContext); + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + +} \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/utils/IntUtil.java b/src/main/java/com/aventstack/extentreports/utils/IntUtil.java new file mode 100644 index 0000000..4ec796b --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/utils/IntUtil.java @@ -0,0 +1,17 @@ +package com.aventstack.extentreports.utils; + +public class IntUtil { + + private IntUtil() { + } + + public static boolean tryParseInt(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + +} \ No newline at end of file From ed05e09be6be31a82a16cff9099e04b7527e962c Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 14:17:15 -0800 Subject: [PATCH 50/77] fixes #59 from API, Klov 0.26+ must be used to utilize this fix --- .../extentreports/ExtentReports.java | 37 +++++++++++++++++++ .../extentreports/ReportObservable.java | 14 ++++++- .../mediastorage/KlovMediaStorageHandler.java | 3 ++ .../impl/HttpMediaManagerImplKlov.java | 4 +- .../aventstack/extentreports/model/Media.java | 9 +++++ .../extentreports/model/ScreenCapture.java | 2 +- .../model/service/ScreenCaptureService.java | 35 ++++++++++++++++++ .../reporter/ExtentKlovReporter.java | 2 - 8 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/aventstack/extentreports/model/service/ScreenCaptureService.java diff --git a/src/main/java/com/aventstack/extentreports/ExtentReports.java b/src/main/java/com/aventstack/extentreports/ExtentReports.java index 0caf258..0b8d410 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentReports.java +++ b/src/main/java/com/aventstack/extentreports/ExtentReports.java @@ -6,7 +6,10 @@ import com.aventstack.extentreports.gherkin.GherkinDialectProvider; import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel; +import com.aventstack.extentreports.model.Media; +import com.aventstack.extentreports.model.ScreenCapture; import com.aventstack.extentreports.model.SystemAttribute; +import com.aventstack.extentreports.reporter.ExtentKlovReporter; import com.aventstack.extentreports.reporter.ExtentReporter; /** @@ -52,6 +55,8 @@ */ public class ExtentReports extends ReportObservable { + private static final String[] IMAGE_PATH_RESOLVER_DIR = new String[] { "target/", "test-output/" }; + /** * Attach a {@link ExtentReporter} reporter, allowing it to access all started * tests, nodes and logs @@ -338,6 +343,38 @@ public void setTestRunnerOutput(List log) { public void setTestRunnerOutput(String log) { setTestRunnerLogs(log); } + + /** + * Tries to resolve a {@link ScreenCapture} location if the supplied path is not found using + * default locations. This can resolve cases where the default path was supplied to be relative + * for a FileReporter. If the absolute path is not determined, the supplied will be used. + * below paths are used to locate the image: + * + *
      + *
    • target/
    • + *
    • test-output//
    • + *
    + * + * @return {@link ExtentKlovReporter} + */ + public ExtentReports tryResolveScreenCapturePath() { + setImagePathResolveDir(IMAGE_PATH_RESOLVER_DIR); + return this; + } + + /** + * Tries to resolve a {@link ScreenCapture} location if the supplied path is not found using + * supplied locations. This can resolve cases where the default path was supplied to be relative + * for a FileReporter. If the absolute path is not determined, the supplied will be used. + * + * @param paths Dirs used to create absolute path of the {@link Media} object + * + * @return {@link ExtentKlovReporter} + */ + public ExtentReports tryResolveScreenCapturePath(String[] paths) { + setImagePathResolveDir(paths); + return this; + } /** * Use this setting when building post-execution reports, such as from TestNG diff --git a/src/main/java/com/aventstack/extentreports/ReportObservable.java b/src/main/java/com/aventstack/extentreports/ReportObservable.java index 94c6ca3..27add73 100644 --- a/src/main/java/com/aventstack/extentreports/ReportObservable.java +++ b/src/main/java/com/aventstack/extentreports/ReportObservable.java @@ -19,6 +19,7 @@ import com.aventstack.extentreports.model.context.SystemAttributeContext; import com.aventstack.extentreports.model.context.TestAttributeTestContextStore; import com.aventstack.extentreports.model.context.helpers.TestRemover; +import com.aventstack.extentreports.model.service.ScreenCaptureService; import com.aventstack.extentreports.model.service.TestService; import com.aventstack.extentreports.reporter.BasicFileReporter; import com.aventstack.extentreports.reporter.ExtentReporter; @@ -171,7 +172,12 @@ abstract class ReportObservable implements ReportService { * */ private Set statusSet = new HashSet(); - + + /** + * Path of dirs to resolve relative image path so there is a direct access + */ + private String[] imagePathResolveDir; + protected ReportObservable() { } @@ -351,6 +357,7 @@ void assignDevice(Test test, Device device) { * @throws IOException thrown if the {@link ScreenCapture} is not found */ void addScreenCapture(Test test, ScreenCapture screenCapture) throws IOException { + ScreenCaptureService.resolvePath(screenCapture, imagePathResolveDir); for (ExtentReporter r : reporterList) { r.onScreenCaptureAdded(test, screenCapture); } @@ -365,6 +372,7 @@ void addScreenCapture(Test test, ScreenCapture screenCapture) throws IOException * @throws IOException thrown if the {@link ScreenCapture} is not found */ void addScreenCapture(Log log, ScreenCapture screenCapture) throws IOException { + ScreenCaptureService.resolvePath(screenCapture, imagePathResolveDir); for (ExtentReporter r : reporterList) { r.onScreenCaptureAdded(log, screenCapture); } @@ -551,6 +559,10 @@ protected void setAnalysisStrategy(AnalysisStrategy strategy) { this.strategy = strategy; stats = new ReportStatusStats(strategy); } + + protected void setImagePathResolveDir(String[] imagePathResolveDir) { + this.imagePathResolveDir = imagePathResolveDir; + } /** * Setting to allow user driven configuration for test time-stamps diff --git a/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java b/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java index d37f432..b233c44 100644 --- a/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java +++ b/src/main/java/com/aventstack/extentreports/mediastorage/KlovMediaStorageHandler.java @@ -32,6 +32,9 @@ public void saveScreenCapture(BasicMongoReportElement el, ScreenCapture media) t .append("sequence", media.getSequence()) .append("test", media.getBsonId().get("testId")); + if (media.isBase64()) { + doc.append("base64String", media.getBase64String()); + } if (el.getClass() != Test.class) { doc.append("log", el.getObjectId()); } else { diff --git a/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java b/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java index 5203149..a671248 100644 --- a/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java +++ b/src/main/java/com/aventstack/extentreports/mediastorage/impl/HttpMediaManagerImplKlov.java @@ -43,7 +43,7 @@ public void storeMedia(Media m) throws IOException { if (m instanceof ScreenCapture && ((ScreenCapture)m).getBase64String() != null) { return; } - File f = new File(m.getPath()); + File f = new File(m.getResolvedPath()); if (!f.exists()) { throw new IOException("The system cannot find the file specified " + m.getPath()); } @@ -61,7 +61,7 @@ public void storeMedia(Media m) throws IOException { builder.addPart("id", new StringBody(m.getBsonId().get("id").toString(), ContentType.TEXT_PLAIN)); builder.addPart("reportId", new StringBody(m.getBsonId().get("reportId").toString(), ContentType.TEXT_PLAIN)); builder.addPart("testId", new StringBody(m.getBsonId().get("testId").toString(), ContentType.TEXT_PLAIN)); - builder.addPart("f", new FileBody(new File(m.getPath()))); + builder.addPart("f", new FileBody(new File(m.getResolvedPath()))); post.setEntity(builder.build()); String logId = m.getBsonId().get("logId") == null ? "" : m.getBsonId().get("logId").toString(); diff --git a/src/main/java/com/aventstack/extentreports/model/Media.java b/src/main/java/com/aventstack/extentreports/model/Media.java index 67c641b..b5343c5 100644 --- a/src/main/java/com/aventstack/extentreports/model/Media.java +++ b/src/main/java/com/aventstack/extentreports/model/Media.java @@ -15,6 +15,7 @@ public class Media implements Serializable { private int sequence; private long fileSize = 0; private Map bsonId; + private String resolvedPath; public String getName() { return name; @@ -67,4 +68,12 @@ public void setBsonId(Map bsonId) { this.bsonId = bsonId; } + public String getResolvedPath() { + return resolvedPath == null ? getPath() : resolvedPath; + } + + public void setResolvedPath(String resolvedPath) { + this.resolvedPath = resolvedPath; + } + } diff --git a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java index fffd628..1562552 100644 --- a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java +++ b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java @@ -23,7 +23,7 @@ public Boolean isBase64() { public String getSource() { if (getBase64String() != null) - return "base64-img"; + return "base64-img"; return ""; } diff --git a/src/main/java/com/aventstack/extentreports/model/service/ScreenCaptureService.java b/src/main/java/com/aventstack/extentreports/model/service/ScreenCaptureService.java new file mode 100644 index 0000000..bc3c0d3 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/model/service/ScreenCaptureService.java @@ -0,0 +1,35 @@ +package com.aventstack.extentreports.model.service; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; + +import com.aventstack.extentreports.model.ScreenCapture; +import com.aventstack.extentreports.utils.FileUtil; + +public class ScreenCaptureService { + + public static void resolvePath(ScreenCapture capture, String[] paths) { + if (paths == null || capture.isBase64()) { + return; + } + String capturePath = capture.getPath(); + String captureFileName = new File(capturePath).getName(); + if (!FileUtil.fileExists(capturePath)) { + for (String p : paths) { + Path path = Paths.get(p, capturePath); + if (path.toFile().exists()) { + capturePath = path.toFile().getAbsolutePath(); + break; + } + path = Paths.get(p, captureFileName); + if (path.toFile().exists()) { + capturePath = path.toFile().getAbsolutePath(); + break; + } + } + } + capture.setResolvedPath(capturePath); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java index 8431620..5375d90 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -311,7 +311,6 @@ public void loadInitializationParams(Properties props) { } private void loadInitializationParams() { - String mongoUri = getConfigValue(DEFAULT_MONGODB_URI_PROP); if (mongoUri == null || mongoUri.isEmpty()) { String mongoHost = getConfigValue(DEFAULT_MONGODB_HOST_PROP); @@ -343,7 +342,6 @@ private void loadInitializationParams() { initKlovServerConnection(uri); } else if (klovHost != null) { initKlovServerConnection(klovHost); - } else { } } From efefc38d792f50598e856a9692c20aba9195c02d Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 21:50:21 -0800 Subject: [PATCH 51/77] removes deprecated MongoClient constructors --- .../reporter/ExtentKlovReporter.java | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java index 5375d90..78a8792 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentKlovReporter.java @@ -41,7 +41,6 @@ import com.mongodb.MongoClient; import com.mongodb.MongoClientOptions; import com.mongodb.MongoClientURI; -import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; @@ -205,34 +204,6 @@ public ExtentKlovReporter initMongoDbConnection(List seeds) { return this; } - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress} and - * {@link MongoCredential} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList) { - mongoClient = new MongoClient(seeds, credentialsList); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress}, - * {@link MongoCredential} and {@link MongoClientOptions} - * - * @param seeds A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(List seeds, List credentialsList, - MongoClientOptions options) { - mongoClient = new MongoClient(seeds, credentialsList, options); - return this; - } - /** * Initializes the Mongo DB connection with a list of {@link ServerAddress} and * {@link MongoClientOptions} @@ -246,34 +217,6 @@ public ExtentKlovReporter initMongoDbConnection(List seeds, Mongo return this; } - /** - * Initializes the Mongo DB connection with {@link ServerAddress} and a list of - * {@link MongoCredential} credentials - * - * @param addr {@link ServerAddress} server address - * @param credentialsList A list of {@link MongoCredential} credentials - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList) { - mongoClient = new MongoClient(addr, credentialsList); - return this; - } - - /** - * Initializes the Mongo DB connection with a list of {@link ServerAddress}, - * {@link MongoCredential} and {@link MongoClientOptions} - * - * @param addr A list of {@link ServerAddress} server addresses - * @param credentialsList A list of {@link MongoCredential} credentials - * @param options {@link MongoClientOptions} options - * @return a {@link ExtentKlovReporter} object - */ - public ExtentKlovReporter initMongoDbConnection(ServerAddress addr, List credentialsList, - MongoClientOptions options) { - mongoClient = new MongoClient(addr, credentialsList, options); - return this; - } - /** * Initializes the Mongo DB connection with a {@link ServerAddress} and * {@link MongoClientOptions} From 9ab21c82c02df788dde52c8aba372d64b2fce25d Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 22:54:56 -0800 Subject: [PATCH 52/77] #103 creates domain for standard and BDD tests --- .../extentreports/ExtentReports.java | 4 ++ .../aventstack/extentreports/ExtentTest.java | 16 +++++++ .../convert/TestModelReportBuilder.java | 42 ++++++++++++++++--- .../aventstack/extentreports/model/Test.java | 7 +++- .../reporter/BasicFileReporter.java | 2 + .../reporter/ConfigurableReporter.java | 2 +- .../extentreports/reporter/JsonFormatter.java | 5 +-- 7 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentReports.java b/src/main/java/com/aventstack/extentreports/ExtentReports.java index 0b8d410..1a3197d 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentReports.java +++ b/src/main/java/com/aventstack/extentreports/ExtentReports.java @@ -392,6 +392,10 @@ public ExtentReports tryResolveScreenCapturePath(String[] paths) { public void setReportUsesManualConfiguration(boolean useManualConfig) { setAllowManualConfig(useManualConfig); } + + public Boolean getReportUsesManualConfiguration() { + return getAllowManualConfig(); + } /** * Type of AnalysisStrategy for the reporter. Not all reporters support this diff --git a/src/main/java/com/aventstack/extentreports/ExtentTest.java b/src/main/java/com/aventstack/extentreports/ExtentTest.java index b97318f..d346436 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentTest.java +++ b/src/main/java/com/aventstack/extentreports/ExtentTest.java @@ -424,6 +424,21 @@ public ExtentTest log(Status status, Throwable t, MediaEntityModelProvider provi public ExtentTest log(Status status, Throwable t) { return log(status, t, null); } + + /** + * Logs an event with {@link ExceptionInfo} + * + * @param status {@link Status} + * @param exceptionInfo{@link ExceptionInfo} + * + * @return An {@link ExtentTest} object + */ + public ExtentTest log(Status status, ExceptionInfo exceptionInfo) { + Log evt = createLog(status); + evt.setExceptionInfo(exceptionInfo); + getModel().getExceptionInfoContext().add(exceptionInfo); + return addLog(evt); + } /** * Logs an Status.INFO event with details and a media object: @@ -1205,4 +1220,5 @@ public ExtentReports getExtent() { void setUseManualConfiguration(Boolean b) { getModel().setUsesManualConfiguration(b); } + } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java b/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java index 9f7dcfe..f9ba958 100644 --- a/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java +++ b/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java @@ -6,6 +6,8 @@ import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.ExtentTest; +import com.aventstack.extentreports.GherkinKeyword; +import com.aventstack.extentreports.model.Log; import com.aventstack.extentreports.model.Test; public class TestModelReportBuilder { @@ -14,17 +16,39 @@ public void recreateModelFromJson(ExtentReports extent, File jsonFile) throws IO if (!jsonFile.exists()) { return; } + Boolean configChanged = extent.getReportUsesManualConfiguration() ? false : true; extent.setReportUsesManualConfiguration(true); List tests = JsonDeserializer.deserialize(jsonFile); for (Test test : tests) { - recreateTest(test, extent.createTest(test.getName(), test.getDescription())); + try { + if (test.getBehaviorDrivenTypeName() == null) { + createDomain(test, extent.createTest(test.getName(), test.getDescription())); + } else { + createDomain(test, extent.createTest(new GherkinKeyword(test.getBehaviorDrivenTypeName()), + test.getName(), test.getDescription())); + + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + if (configChanged) { + extent.setReportUsesManualConfiguration(false); } - extent.setReportUsesManualConfiguration(false); } - public void recreateTest(Test test, ExtentTest extentTest) { + public void createDomain(Test test, ExtentTest extentTest) throws ClassNotFoundException { + extentTest.getModel().setStartTime(test.getStartTime()); + extentTest.getModel().setEndTime(test.getEndTime()); + extentTest.getModel().computeEndTimeFromChildren(); + // create events - test.getLogContext().getAll().forEach(x -> extentTest.log(x.getStatus(), x.getDetails())); + for (Log log : test.getLogContext().getAll()) { + if (log.getDetails() != null) + extentTest.log(log.getStatus(), log.getDetails()); + if (log.getExceptionInfo() != null) + extentTest.log(log.getStatus(), log.getExceptionInfo()); + } // assign attributes test.getAuthorContext().getAll().forEach(x -> extentTest.assignAuthor(x.getName())); @@ -33,8 +57,14 @@ public void recreateTest(Test test, ExtentTest extentTest) { // handle nodes for (Test node : test.getNodeContext().getAll()) { - ExtentTest extentNode = extentTest.createNode(node.getName()); - recreateTest(node, extentNode); + ExtentTest extentNode = null; + if (node.getBehaviorDrivenTypeName() == null) { + extentNode = extentTest.createNode(node.getName(), node.getDescription()); + } else { + extentNode = extentTest.createNode(new GherkinKeyword(node.getBehaviorDrivenTypeName()), node.getName(), + node.getDescription()); + } + createDomain(node, extentNode); } } diff --git a/src/main/java/com/aventstack/extentreports/model/Test.java b/src/main/java/com/aventstack/extentreports/model/Test.java index f0fb804..089b38a 100644 --- a/src/main/java/com/aventstack/extentreports/model/Test.java +++ b/src/main/java/com/aventstack/extentreports/model/Test.java @@ -314,7 +314,7 @@ public void end() { endChildrenRecursive(this); status = (status == Status.INFO || status == Status.DEBUG) ? Status.PASS : status; if (!usesManualConfiguration) { - setEndTimeFromChildren(); + computeEndTimeFromChildren(); } } @@ -345,7 +345,7 @@ private void endChildrenRecursive(Test test) { test.getNodeContext().getAll().forEach(Test::end); } - private void setEndTimeFromChildren() { + public void computeEndTimeFromChildren() { if (!getNodeContext().isEmpty()) { setStartTime(getNodeContext().getFirst().getStartTime()); setEndTime(getNodeContext().getLast().getEndTime()); @@ -356,6 +356,9 @@ private void setEndTimeFromChildren() { } public String getBehaviorDrivenTypeName() { + if (bddTypeName != null) { + return bddTypeName; + } try { Method method = bddType.getMethod("getGherkinName"); Object o = method.invoke(null, (Object[]) null); diff --git a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java index aab016b..92cf3b3 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/BasicFileReporter.java @@ -129,6 +129,8 @@ public void onScreenCaptureAdded(Log log, ScreenCapture screenCapture) throws IO } private void onScreenCaptureAdded(ScreenCapture screenCapture) throws IOException { + if (getConfigurationStore() == null) + return; String autoCreateRelativePathMedia = (String) getConfigurationStore() .getConfig(DEFAULT_MEDIA_SAVE_PROPERTY_NAME); if (autoCreateRelativePathMedia != null && Boolean.valueOf(autoCreateRelativePathMedia)) { diff --git a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java index 6c4e5e7..44b57d6 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ConfigurableReporter.java @@ -123,7 +123,7 @@ protected void loadInternalReporterConfiguration(String[] configFilePath) { * entries */ public ConfigurationStore getConfigurationStore() { - return basicConfiguration.getConfigurationStore(); + return basicConfiguration == null ? null : basicConfiguration.getConfigurationStore(); } } \ No newline at end of file diff --git a/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java b/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java index a4a40ce..1e4b062 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/JsonFormatter.java @@ -29,11 +29,10 @@ public void start() { public synchronized void flush(ReportAggregates reportAggregates) { super.flush(reportAggregates); GsonBuilder builder = new GsonBuilder(); - //builder.registerTypeAdapter(Given.class, new GherkinModelSerializer()); Gson gson = builder.create(); try (FileWriter writer = new FileWriter(getFilePath())) { - List l = reportAggregates.getTestList(); - gson.toJson(l, writer); + List list = reportAggregates.getTestList(); + gson.toJson(list, writer); } catch (IOException e) { e.printStackTrace(); } From 20ff02238c5516292b0232b0c8019a1cf7a200c7 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 22:59:55 -0800 Subject: [PATCH 53/77] remove deprecation for Logger/Html reporters --- .../aventstack/extentreports/reporter/ExtentHtmlReporter.java | 1 - .../aventstack/extentreports/reporter/ExtentLoggerReporter.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java index 93ec7da..11c7d40 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentHtmlReporter.java @@ -15,7 +15,6 @@ * The ExtentSparkReporter creates a rich standalone spark file. It allows * several configuration options via the config() method. */ -@Deprecated public class ExtentHtmlReporter extends BasicFileReporter { private static final Logger logger = Logger.getLogger(ExtentHtmlReporter.class.getName()); diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java index da68576..27accad 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentLoggerReporter.java @@ -15,7 +15,6 @@ * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several * configuration options via the config() method. */ -@Deprecated public class ExtentLoggerReporter extends BasicFileReporter { private static final Logger logger = Logger.getLogger(ExtentLoggerReporter.class.getName()); From 1bb39c369a6dd5f21a49d4a6f1d3689a80ad48df Mon Sep 17 00:00:00 2001 From: anshooarora Date: Fri, 3 Jan 2020 23:00:48 -0800 Subject: [PATCH 54/77] rename method --- .../extentreports/convert/TestModelReportBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java b/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java index f9ba958..eeef8a9 100644 --- a/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java +++ b/src/main/java/com/aventstack/extentreports/convert/TestModelReportBuilder.java @@ -12,7 +12,7 @@ public class TestModelReportBuilder { - public void recreateModelFromJson(ExtentReports extent, File jsonFile) throws IOException { + public void createDomainFromJsonArchive(ExtentReports extent, File jsonFile) throws IOException { if (!jsonFile.exists()) { return; } From 0ce9dbd63b57b596daff8065a2854ade931664e9 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sat, 4 Jan 2020 23:16:49 -0800 Subject: [PATCH 55/77] thinner topnav --- .../offline/spark/css/spark-style.css | 32 +++++++++++-------- .../view/spark/partials/head.ftl | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css index bb635d8..23b9f2c 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css @@ -8,15 +8,9 @@ */: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,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%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-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:#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;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}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}dfn{font-style:italic}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;-webkit-text-decoration-skip:objects}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:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}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}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[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-cancel-button,[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-family:inherit;font-weight:500;line-height:1.2;color:inherit}.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,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}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:-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,.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%;min-height:1px;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%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@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%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@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%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@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%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@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%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.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.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.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.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.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.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.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.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.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 .table{background-color:#fff}.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-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.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-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-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-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-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-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-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-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:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.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{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;-ms-overflow-style:-ms-autohiding-scrollbar}.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;-ms-overflow-style:-ms-autohiding-scrollbar}.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;-ms-overflow-style:-ms-autohiding-scrollbar}.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;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;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}.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::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}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;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.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-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.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-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.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:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.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:.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:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control: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,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control: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{background-color:#71dd8a}.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{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 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.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~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.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{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:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control: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,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control: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{background-color:#efa2a9}.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{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 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.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~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.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{box-shadow:0 0 0 .2rem rgba(220,53,69,.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{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;margin-top:0;margin-right:.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;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;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}.btn:focus,.btn:hover{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}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}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(0,123,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(0,123,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(108,117,125,.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(108,117,125,.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(40,167,69,.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(40,167,69,.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(23,162,184,.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(23,162,184,.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(255,193,7,.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(255,193,7,.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(220,53,69,.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(220,53,69,.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(248,249,250,.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(248,249,250,.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(52,58,64,.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(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent;background-image:none;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;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.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{opacity:0;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;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}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;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{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;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{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;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-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;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}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 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-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.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:first-child{margin-left:0}.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{margin-left: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{-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+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-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:-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>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.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{margin-left:-1px}.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:-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::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-webkit-box;display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.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:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;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>.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:-webkit-inline-box;display:-ms-inline-flexbox;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;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-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{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%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{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%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::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%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-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%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;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.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{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;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(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.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:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.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{-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:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{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:.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:-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:.5rem;padding-bottom:.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:.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:not(:disabled):not(.disabled){cursor:pointer}.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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-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}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-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}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-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}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@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{-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 .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-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-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.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{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 .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-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-expand .dropup .dropdown-menu{top:auto;bottom:100%}.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;charset=utf8,%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;charset=utf8,%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:-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,.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{-webkit-box-flex:1;-ms-flex:1 1 auto;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:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-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{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-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:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.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:-webkit-box;display:-ms-flexbox;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{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-link:not(:disabled):not(.disabled){cursor:pointer}.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}.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}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.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}@-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:.75rem;background-color:#e9ecef;border-radius:.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;color:#fff;text-align:center;background-color:#007bff;transition:width .6s ease}.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{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.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:focus,.list-group-item-action:hover{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:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{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:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.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% - (.5rem * 2))}.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,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.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;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding: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;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.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-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-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:-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::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom: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-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::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left: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-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::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;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::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;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-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;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:.5}.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:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%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;charset=utf8,%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:10px;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{position:relative;-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;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.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{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-circle{border-radius:50%!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 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.857143%}.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}.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}.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}.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}.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}.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}}.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;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;-webkit-clip-path:none;clip-path:none}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.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-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-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-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-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-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-justify{text-align:justify!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-normal{font-weight:400!important}.font-weight-bold{font-weight:700!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:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-muted{color:#6c757d!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.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 #ddd!important}} /*# sourceMappingURL=bootstrap.min.css.map */ - - - /* perfect-scrollbar v0.6.16 */ .ps-container{-ms-touch-action:auto;touch-action:auto;overflow:hidden !important;-ms-overflow-style:none}@supports (-ms-overflow-style: none){.ps-container{overflow:auto !important}}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){.ps-container{overflow:auto !important}}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block;background-color:transparent}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;bottom:0px;height:15px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;bottom:2px;height:6px}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x,.ps-container>.ps-scrollbar-x-rail:active>.ps-scrollbar-x{height:11px}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;right:0;width:15px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;right:2px;width:6px}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y,.ps-container>.ps-scrollbar-y-rail:active>.ps-scrollbar-y{width:11px}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999} - - - @charset "UTF-8"; /*! @@ -39,11 +33,8 @@ */ .red{background-color:#F44336!important}.red-text{color:#F44336!important}.red.lighten-5{background-color:#FFEBEE!important}.red-text.text-lighten-5{color:#FFEBEE!important}.red.lighten-4{background-color:#FFCDD2!important}.red-text.text-lighten-4{color:#FFCDD2!important}.red.lighten-3{background-color:#EF9A9A!important}.red-text.text-lighten-3{color:#EF9A9A!important}.red.lighten-2{background-color:#E57373!important}.red-text.text-lighten-2{color:#E57373!important}.red.lighten-1{background-color:#EF5350!important}.red-text.text-lighten-1{color:#EF5350!important}.red.darken-1{background-color:#E53935!important}.red-text.text-darken-1{color:#E53935!important}.red.darken-2{background-color:#D32F2F!important}.red-text.text-darken-2{color:#D32F2F!important}.red.darken-3{background-color:#C62828!important}.red-text.text-darken-3{color:#C62828!important}.red.darken-4{background-color:#B71C1C!important}.red-text.text-darken-4{color:#B71C1C!important}.red.accent-1{background-color:#FF8A80!important}.red-text.text-accent-1{color:#FF8A80!important}.red.accent-2{background-color:#FF5252!important}.red-text.text-accent-2{color:#FF5252!important}.red.accent-3{background-color:#FF1744!important}.red-text.text-accent-3{color:#FF1744!important}.red.accent-4{background-color:#D50000!important}.red-text.text-accent-4{color:#D50000!important}.pink{background-color:#e91e63!important}.pink-text{color:#e91e63!important}.pink.lighten-5{background-color:#fce4ec!important}.pink-text.text-lighten-5{color:#fce4ec!important}.pink.lighten-4{background-color:#f8bbd0!important}.pink-text.text-lighten-4{color:#f8bbd0!important}.pink.lighten-3{background-color:#f48fb1!important}.pink-text.text-lighten-3{color:#f48fb1!important}.pink.lighten-2{background-color:#f06292!important}.pink-text.text-lighten-2{color:#f06292!important}.pink.lighten-1{background-color:#ec407a!important}.pink-text.text-lighten-1{color:#ec407a!important}.pink.darken-1{background-color:#d81b60!important}.pink-text.text-darken-1{color:#d81b60!important}.pink.darken-2{background-color:#c2185b!important}.pink-text.text-darken-2{color:#c2185b!important}.pink.darken-3{background-color:#ad1457!important}.pink-text.text-darken-3{color:#ad1457!important}.pink.darken-4{background-color:#880e4f!important}.pink-text.text-darken-4{color:#880e4f!important}.pink.accent-1{background-color:#ff80ab!important}.pink-text.text-accent-1{color:#ff80ab!important}.pink.accent-2{background-color:#ff4081!important}.pink-text.text-accent-2{color:#ff4081!important}.pink.accent-3{background-color:#f50057!important}.pink-text.text-accent-3{color:#f50057!important}.pink.accent-4{background-color:#c51162!important}.pink-text.text-accent-4{color:#c51162!important}.purple{background-color:#9c27b0!important}.purple-text{color:#9c27b0!important}.purple.lighten-5{background-color:#f3e5f5!important}.purple-text.text-lighten-5{color:#f3e5f5!important}.purple.lighten-4{background-color:#e1bee7!important}.purple-text.text-lighten-4{color:#e1bee7!important}.purple.lighten-3{background-color:#ce93d8!important}.purple-text.text-lighten-3{color:#ce93d8!important}.purple.lighten-2{background-color:#ba68c8!important}.purple-text.text-lighten-2{color:#ba68c8!important}.purple.lighten-1{background-color:#ab47bc!important}.purple-text.text-lighten-1{color:#ab47bc!important}.purple.darken-1{background-color:#8e24aa!important}.purple-text.text-darken-1{color:#8e24aa!important}.purple.darken-2{background-color:#7b1fa2!important}.purple-text.text-darken-2{color:#7b1fa2!important}.purple.darken-3{background-color:#6a1b9a!important}.purple-text.text-darken-3{color:#6a1b9a!important}.purple.darken-4{background-color:#4a148c!important}.purple-text.text-darken-4{color:#4a148c!important}.purple.accent-1{background-color:#ea80fc!important}.purple-text.text-accent-1{color:#ea80fc!important}.purple.accent-2{background-color:#e040fb!important}.purple-text.text-accent-2{color:#e040fb!important}.purple.accent-3{background-color:#d500f9!important}.purple-text.text-accent-3{color:#d500f9!important}.purple.accent-4{background-color:#a0f!important}.purple-text.text-accent-4{color:#a0f!important}.deep-purple{background-color:#673ab7!important}.deep-purple-text{color:#673ab7!important}.deep-purple.lighten-5{background-color:#ede7f6!important}.deep-purple-text.text-lighten-5{color:#ede7f6!important}.deep-purple.lighten-4{background-color:#d1c4e9!important}.deep-purple-text.text-lighten-4{color:#d1c4e9!important}.deep-purple.lighten-3{background-color:#b39ddb!important}.deep-purple-text.text-lighten-3{color:#b39ddb!important}.deep-purple.lighten-2{background-color:#9575cd!important}.deep-purple-text.text-lighten-2{color:#9575cd!important}.deep-purple.lighten-1{background-color:#7e57c2!important}.deep-purple-text.text-lighten-1{color:#7e57c2!important}.deep-purple.darken-1{background-color:#5e35b1!important}.deep-purple-text.text-darken-1{color:#5e35b1!important}.deep-purple.darken-2{background-color:#512da8!important}.deep-purple-text.text-darken-2{color:#512da8!important}.deep-purple.darken-3{background-color:#4527a0!important}.deep-purple-text.text-darken-3{color:#4527a0!important}.deep-purple.darken-4{background-color:#311b92!important}.deep-purple-text.text-darken-4{color:#311b92!important}.deep-purple.accent-1{background-color:#b388ff!important}.deep-purple-text.text-accent-1{color:#b388ff!important}.deep-purple.accent-2{background-color:#7c4dff!important}.deep-purple-text.text-accent-2{color:#7c4dff!important}.deep-purple.accent-3{background-color:#651fff!important}.deep-purple-text.text-accent-3{color:#651fff!important}.deep-purple.accent-4{background-color:#6200ea!important}.deep-purple-text.text-accent-4{color:#6200ea!important}.indigo{background-color:#3f51b5!important}.indigo-text{color:#3f51b5!important}.indigo.lighten-5{background-color:#e8eaf6!important}.indigo-text.text-lighten-5{color:#e8eaf6!important}.indigo.lighten-4{background-color:#c5cae9!important}.indigo-text.text-lighten-4{color:#c5cae9!important}.indigo.lighten-3{background-color:#9fa8da!important}.indigo-text.text-lighten-3{color:#9fa8da!important}.indigo.lighten-2{background-color:#7986cb!important}.indigo-text.text-lighten-2{color:#7986cb!important}.indigo.lighten-1{background-color:#5c6bc0!important}.indigo-text.text-lighten-1{color:#5c6bc0!important}.indigo.darken-1{background-color:#3949ab!important}.indigo-text.text-darken-1{color:#3949ab!important}.indigo.darken-2{background-color:#303f9f!important}.indigo-text.text-darken-2{color:#303f9f!important}.indigo.darken-3{background-color:#283593!important}.indigo-text.text-darken-3{color:#283593!important}.indigo.darken-4{background-color:#1a237e!important}.indigo-text.text-darken-4{color:#1a237e!important}.indigo.accent-1{background-color:#8c9eff!important}.indigo-text.text-accent-1{color:#8c9eff!important}.indigo.accent-2{background-color:#536dfe!important}.indigo-text.text-accent-2{color:#536dfe!important}.indigo.accent-3{background-color:#3d5afe!important}.indigo-text.text-accent-3{color:#3d5afe!important}.indigo.accent-4{background-color:#304ffe!important}.indigo-text.text-accent-4{color:#304ffe!important}.blue{background-color:#2196F3!important}.blue-text{color:#2196F3!important}.blue.lighten-5{background-color:#E3F2FD!important}.blue-text.text-lighten-5{color:#E3F2FD!important}.blue.lighten-4{background-color:#BBDEFB!important}.blue-text.text-lighten-4{color:#BBDEFB!important}.blue.lighten-3{background-color:#90CAF9!important}.blue-text.text-lighten-3{color:#90CAF9!important}.blue.lighten-2{background-color:#64B5F6!important}.blue-text.text-lighten-2{color:#64B5F6!important}.blue.lighten-1{background-color:#42A5F5!important}.blue-text.text-lighten-1{color:#42A5F5!important}.blue.darken-1{background-color:#1E88E5!important}.blue-text.text-darken-1{color:#1E88E5!important}.blue.darken-2{background-color:#1976D2!important}.blue-text.text-darken-2{color:#1976D2!important}.blue.darken-3{background-color:#1565C0!important}.blue-text.text-darken-3{color:#1565C0!important}.blue.darken-4{background-color:#0D47A1!important}.blue-text.text-darken-4{color:#0D47A1!important}.blue.accent-1{background-color:#82B1FF!important}.blue-text.text-accent-1{color:#82B1FF!important}.blue.accent-2{background-color:#448AFF!important}.blue-text.text-accent-2{color:#448AFF!important}.blue.accent-3{background-color:#2979FF!important}.blue-text.text-accent-3{color:#2979FF!important}.blue.accent-4{background-color:#2962FF!important}.blue-text.text-accent-4{color:#2962FF!important}.light-blue{background-color:#03a9f4!important}.light-blue-text{color:#03a9f4!important}.light-blue.lighten-5{background-color:#e1f5fe!important}.light-blue-text.text-lighten-5{color:#e1f5fe!important}.light-blue.lighten-4{background-color:#b3e5fc!important}.light-blue-text.text-lighten-4{color:#b3e5fc!important}.light-blue.lighten-3{background-color:#81d4fa!important}.light-blue-text.text-lighten-3{color:#81d4fa!important}.light-blue.lighten-2{background-color:#4fc3f7!important}.light-blue-text.text-lighten-2{color:#4fc3f7!important}.light-blue.lighten-1{background-color:#29b6f6!important}.light-blue-text.text-lighten-1{color:#29b6f6!important}.light-blue.darken-1{background-color:#039be5!important}.light-blue-text.text-darken-1{color:#039be5!important}.light-blue.darken-2{background-color:#0288d1!important}.light-blue-text.text-darken-2{color:#0288d1!important}.light-blue.darken-3{background-color:#0277bd!important}.light-blue-text.text-darken-3{color:#0277bd!important}.light-blue.darken-4{background-color:#01579b!important}.light-blue-text.text-darken-4{color:#01579b!important}.light-blue.accent-1{background-color:#80d8ff!important}.light-blue-text.text-accent-1{color:#80d8ff!important}.light-blue.accent-2{background-color:#40c4ff!important}.light-blue-text.text-accent-2{color:#40c4ff!important}.light-blue.accent-3{background-color:#00b0ff!important}.light-blue-text.text-accent-3{color:#00b0ff!important}.light-blue.accent-4{background-color:#0091ea!important}.light-blue-text.text-accent-4{color:#0091ea!important}.cyan{background-color:#00bcd4!important}.cyan-text{color:#00bcd4!important}.cyan.lighten-5{background-color:#e0f7fa!important}.cyan-text.text-lighten-5{color:#e0f7fa!important}.cyan.lighten-4{background-color:#b2ebf2!important}.cyan-text.text-lighten-4{color:#b2ebf2!important}.cyan.lighten-3{background-color:#80deea!important}.cyan-text.text-lighten-3{color:#80deea!important}.cyan.lighten-2{background-color:#4dd0e1!important}.cyan-text.text-lighten-2{color:#4dd0e1!important}.cyan.lighten-1{background-color:#26c6da!important}.cyan-text.text-lighten-1{color:#26c6da!important}.cyan.darken-1{background-color:#00acc1!important}.cyan-text.text-darken-1{color:#00acc1!important}.cyan.darken-2{background-color:#0097a7!important}.cyan-text.text-darken-2{color:#0097a7!important}.cyan.darken-3{background-color:#00838f!important}.cyan-text.text-darken-3{color:#00838f!important}.cyan.darken-4{background-color:#006064!important}.cyan-text.text-darken-4{color:#006064!important}.cyan.accent-1{background-color:#84ffff!important}.cyan-text.text-accent-1{color:#84ffff!important}.cyan.accent-2{background-color:#18ffff!important}.cyan-text.text-accent-2{color:#18ffff!important}.cyan.accent-3{background-color:#00e5ff!important}.cyan-text.text-accent-3{color:#00e5ff!important}.cyan.accent-4{background-color:#00b8d4!important}.cyan-text.text-accent-4{color:#00b8d4!important}.teal{background-color:#009688!important}.teal-text{color:#009688!important}.teal.lighten-5{background-color:#e0f2f1!important}.teal-text.text-lighten-5{color:#e0f2f1!important}.teal.lighten-4{background-color:#b2dfdb!important}.teal-text.text-lighten-4{color:#b2dfdb!important}.teal.lighten-3{background-color:#80cbc4!important}.teal-text.text-lighten-3{color:#80cbc4!important}.teal.lighten-2{background-color:#4db6ac!important}.teal-text.text-lighten-2{color:#4db6ac!important}.teal.lighten-1{background-color:#26a69a!important}.teal-text.text-lighten-1{color:#26a69a!important}.teal.darken-1{background-color:#00897b!important}.teal-text.text-darken-1{color:#00897b!important}.teal.darken-2{background-color:#00796b!important}.teal-text.text-darken-2{color:#00796b!important}.teal.darken-3{background-color:#00695c!important}.teal-text.text-darken-3{color:#00695c!important}.teal.darken-4{background-color:#004d40!important}.teal-text.text-darken-4{color:#004d40!important}.teal.accent-1{background-color:#a7ffeb!important}.teal-text.text-accent-1{color:#a7ffeb!important}.teal.accent-2{background-color:#64ffda!important}.teal-text.text-accent-2{color:#64ffda!important}.teal.accent-3{background-color:#1de9b6!important}.teal-text.text-accent-3{color:#1de9b6!important}.teal.accent-4{background-color:#00bfa5!important}.teal-text.text-accent-4{color:#00bfa5!important}.green{background-color:#4CAF50!important}.green-text{color:#4CAF50!important}.green.lighten-5{background-color:#E8F5E9!important}.green-text.text-lighten-5{color:#E8F5E9!important}.green.lighten-4{background-color:#C8E6C9!important}.green-text.text-lighten-4{color:#C8E6C9!important}.green.lighten-3{background-color:#A5D6A7!important}.green-text.text-lighten-3{color:#A5D6A7!important}.green.lighten-2{background-color:#81C784!important}.green-text.text-lighten-2{color:#81C784!important}.green.lighten-1{background-color:#66BB6A!important}.green-text.text-lighten-1{color:#66BB6A!important}.green.darken-1{background-color:#43A047!important}.green-text.text-darken-1{color:#43A047!important}.green.darken-2{background-color:#388E3C!important}.green-text.text-darken-2{color:#388E3C!important}.green.darken-3{background-color:#2E7D32!important}.green-text.text-darken-3{color:#2E7D32!important}.green.darken-4{background-color:#1B5E20!important}.green-text.text-darken-4{color:#1B5E20!important}.green.accent-1{background-color:#B9F6CA!important}.green-text.text-accent-1{color:#B9F6CA!important}.green.accent-2{background-color:#69F0AE!important}.green-text.text-accent-2{color:#69F0AE!important}.green.accent-3{background-color:#00E676!important}.green-text.text-accent-3{color:#00E676!important}.green.accent-4{background-color:#00C853!important}.green-text.text-accent-4{color:#00C853!important}.light-green{background-color:#8bc34a!important}.light-green-text{color:#8bc34a!important}.light-green.lighten-5{background-color:#f1f8e9!important}.light-green-text.text-lighten-5{color:#f1f8e9!important}.light-green.lighten-4{background-color:#dcedc8!important}.light-green-text.text-lighten-4{color:#dcedc8!important}.light-green.lighten-3{background-color:#c5e1a5!important}.light-green-text.text-lighten-3{color:#c5e1a5!important}.light-green.lighten-2{background-color:#aed581!important}.light-green-text.text-lighten-2{color:#aed581!important}.light-green.lighten-1{background-color:#9ccc65!important}.light-green-text.text-lighten-1{color:#9ccc65!important}.light-green.darken-1{background-color:#7cb342!important}.light-green-text.text-darken-1{color:#7cb342!important}.light-green.darken-2{background-color:#689f38!important}.light-green-text.text-darken-2{color:#689f38!important}.light-green.darken-3{background-color:#558b2f!important}.light-green-text.text-darken-3{color:#558b2f!important}.light-green.darken-4{background-color:#33691e!important}.light-green-text.text-darken-4{color:#33691e!important}.light-green.accent-1{background-color:#ccff90!important}.light-green-text.text-accent-1{color:#ccff90!important}.light-green.accent-2{background-color:#b2ff59!important}.light-green-text.text-accent-2{color:#b2ff59!important}.light-green.accent-3{background-color:#76ff03!important}.light-green-text.text-accent-3{color:#76ff03!important}.light-green.accent-4{background-color:#64dd17!important}.light-green-text.text-accent-4{color:#64dd17!important}.lime{background-color:#cddc39!important}.lime-text{color:#cddc39!important}.lime.lighten-5{background-color:#f9fbe7!important}.lime-text.text-lighten-5{color:#f9fbe7!important}.lime.lighten-4{background-color:#f0f4c3!important}.lime-text.text-lighten-4{color:#f0f4c3!important}.lime.lighten-3{background-color:#e6ee9c!important}.lime-text.text-lighten-3{color:#e6ee9c!important}.lime.lighten-2{background-color:#dce775!important}.lime-text.text-lighten-2{color:#dce775!important}.lime.lighten-1{background-color:#d4e157!important}.lime-text.text-lighten-1{color:#d4e157!important}.lime.darken-1{background-color:#c0ca33!important}.lime-text.text-darken-1{color:#c0ca33!important}.lime.darken-2{background-color:#afb42b!important}.lime-text.text-darken-2{color:#afb42b!important}.lime.darken-3{background-color:#9e9d24!important}.lime-text.text-darken-3{color:#9e9d24!important}.lime.darken-4{background-color:#827717!important}.lime-text.text-darken-4{color:#827717!important}.lime.accent-1{background-color:#f4ff81!important}.lime-text.text-accent-1{color:#f4ff81!important}.lime.accent-2{background-color:#eeff41!important}.lime-text.text-accent-2{color:#eeff41!important}.lime.accent-3{background-color:#c6ff00!important}.lime-text.text-accent-3{color:#c6ff00!important}.lime.accent-4{background-color:#aeea00!important}.lime-text.text-accent-4{color:#aeea00!important}.yellow{background-color:#ffeb3b!important}.yellow-text{color:#ffeb3b!important}.yellow.lighten-5{background-color:#fffde7!important}.yellow-text.text-lighten-5{color:#fffde7!important}.yellow.lighten-4{background-color:#fff9c4!important}.yellow-text.text-lighten-4{color:#fff9c4!important}.yellow.lighten-3{background-color:#fff59d!important}.yellow-text.text-lighten-3{color:#fff59d!important}.yellow.lighten-2{background-color:#fff176!important}.yellow-text.text-lighten-2{color:#fff176!important}.yellow.lighten-1{background-color:#ffee58!important}.yellow-text.text-lighten-1{color:#ffee58!important}.yellow.darken-1{background-color:#fdd835!important}.yellow-text.text-darken-1{color:#fdd835!important}.yellow.darken-2{background-color:#fbc02d!important}.yellow-text.text-darken-2{color:#fbc02d!important}.yellow.darken-3{background-color:#f9a825!important}.yellow-text.text-darken-3{color:#f9a825!important}.yellow.darken-4{background-color:#f57f17!important}.yellow-text.text-darken-4{color:#f57f17!important}.yellow.accent-1{background-color:#ffff8d!important}.yellow-text.text-accent-1{color:#ffff8d!important}.yellow.accent-2{background-color:#ff0!important}.yellow-text.text-accent-2{color:#ff0!important}.yellow.accent-3{background-color:#ffea00!important}.yellow-text.text-accent-3{color:#ffea00!important}.yellow.accent-4{background-color:#ffd600!important}.yellow-text.text-accent-4{color:#ffd600!important}.amber{background-color:#ffc107!important}.amber-text{color:#ffc107!important}.amber.lighten-5{background-color:#fff8e1!important}.amber-text.text-lighten-5{color:#fff8e1!important}.amber.lighten-4{background-color:#ffecb3!important}.amber-text.text-lighten-4{color:#ffecb3!important}.amber.lighten-3{background-color:#ffe082!important}.amber-text.text-lighten-3{color:#ffe082!important}.amber.lighten-2{background-color:#ffd54f!important}.amber-text.text-lighten-2{color:#ffd54f!important}.amber.lighten-1{background-color:#ffca28!important}.amber-text.text-lighten-1{color:#ffca28!important}.amber.darken-1{background-color:#ffb300!important}.amber-text.text-darken-1{color:#ffb300!important}.amber.darken-2{background-color:#ffa000!important}.amber-text.text-darken-2{color:#ffa000!important}.amber.darken-3{background-color:#ff8f00!important}.amber-text.text-darken-3{color:#ff8f00!important}.amber.darken-4{background-color:#ff6f00!important}.amber-text.text-darken-4{color:#ff6f00!important}.amber.accent-1{background-color:#ffe57f!important}.amber-text.text-accent-1{color:#ffe57f!important}.amber.accent-2{background-color:#ffd740!important}.amber-text.text-accent-2{color:#ffd740!important}.amber.accent-3{background-color:#ffc400!important}.amber-text.text-accent-3{color:#ffc400!important}.amber.accent-4{background-color:#ffab00!important}.amber-text.text-accent-4{color:#ffab00!important}.orange{background-color:#ff9800!important}.orange-text{color:#ff9800!important}.orange.lighten-5{background-color:#fff3e0!important}.orange-text.text-lighten-5{color:#fff3e0!important}.orange.lighten-4{background-color:#ffe0b2!important}.orange-text.text-lighten-4{color:#ffe0b2!important}.orange.lighten-3{background-color:#ffcc80!important}.orange-text.text-lighten-3{color:#ffcc80!important}.orange.lighten-2{background-color:#ffb74d!important}.orange-text.text-lighten-2{color:#ffb74d!important}.orange.lighten-1{background-color:#ffa726!important}.orange-text.text-lighten-1{color:#ffa726!important}.orange.darken-1{background-color:#fb8c00!important}.orange-text.text-darken-1{color:#fb8c00!important}.orange.darken-2{background-color:#f57c00!important}.orange-text.text-darken-2{color:#f57c00!important}.orange.darken-3{background-color:#ef6c00!important}.orange-text.text-darken-3{color:#ef6c00!important}.orange.darken-4{background-color:#e65100!important}.orange-text.text-darken-4{color:#e65100!important}.orange.accent-1{background-color:#ffd180!important}.orange-text.text-accent-1{color:#ffd180!important}.orange.accent-2{background-color:#ffab40!important}.orange-text.text-accent-2{color:#ffab40!important}.orange.accent-3{background-color:#ff9100!important}.orange-text.text-accent-3{color:#ff9100!important}.orange.accent-4{background-color:#ff6d00!important}.orange-text.text-accent-4{color:#ff6d00!important}.deep-orange{background-color:#ff5722!important}.deep-orange-text{color:#ff5722!important}.deep-orange.lighten-5{background-color:#fbe9e7!important}.deep-orange-text.text-lighten-5{color:#fbe9e7!important}.deep-orange.lighten-4{background-color:#ffccbc!important}.deep-orange-text.text-lighten-4{color:#ffccbc!important}.deep-orange.lighten-3{background-color:#ffab91!important}.deep-orange-text.text-lighten-3{color:#ffab91!important}.deep-orange.lighten-2{background-color:#ff8a65!important}.deep-orange-text.text-lighten-2{color:#ff8a65!important}.deep-orange.lighten-1{background-color:#ff7043!important}.deep-orange-text.text-lighten-1{color:#ff7043!important}.deep-orange.darken-1{background-color:#f4511e!important}.deep-orange-text.text-darken-1{color:#f4511e!important}.deep-orange.darken-2{background-color:#e64a19!important}.deep-orange-text.text-darken-2{color:#e64a19!important}.deep-orange.darken-3{background-color:#d84315!important}.deep-orange-text.text-darken-3{color:#d84315!important}.deep-orange.darken-4{background-color:#bf360c!important}.deep-orange-text.text-darken-4{color:#bf360c!important}.deep-orange.accent-1{background-color:#ff9e80!important}.deep-orange-text.text-accent-1{color:#ff9e80!important}.deep-orange.accent-2{background-color:#ff6e40!important}.deep-orange-text.text-accent-2{color:#ff6e40!important}.deep-orange.accent-3{background-color:#ff3d00!important}.deep-orange-text.text-accent-3{color:#ff3d00!important}.deep-orange.accent-4{background-color:#dd2c00!important}.deep-orange-text.text-accent-4{color:#dd2c00!important}.brown{background-color:#795548!important}.brown-text{color:#795548!important}.brown.lighten-5{background-color:#efebe9!important}.brown-text.text-lighten-5{color:#efebe9!important}.brown.lighten-4{background-color:#d7ccc8!important}.brown-text.text-lighten-4{color:#d7ccc8!important}.brown.lighten-3{background-color:#bcaaa4!important}.brown-text.text-lighten-3{color:#bcaaa4!important}.brown.lighten-2{background-color:#a1887f!important}.brown-text.text-lighten-2{color:#a1887f!important}.brown.lighten-1{background-color:#8d6e63!important}.brown-text.text-lighten-1{color:#8d6e63!important}.brown.darken-1{background-color:#6d4c41!important}.brown-text.text-darken-1{color:#6d4c41!important}.brown.darken-2{background-color:#5d4037!important}.brown-text.text-darken-2{color:#5d4037!important}.brown.darken-3{background-color:#4e342e!important}.brown-text.text-darken-3{color:#4e342e!important}.brown.darken-4{background-color:#3e2723!important}.brown-text.text-darken-4{color:#3e2723!important}.blue-grey{background-color:#607d8b!important}.blue-grey-text{color:#607d8b!important}.blue-grey.lighten-5{background-color:#eceff1!important}.blue-grey-text.text-lighten-5{color:#eceff1!important}.blue-grey.lighten-4{background-color:#cfd8dc!important}.blue-grey-text.text-lighten-4{color:#cfd8dc!important}.blue-grey.lighten-3{background-color:#b0bec5!important}.blue-grey-text.text-lighten-3{color:#b0bec5!important}.blue-grey.lighten-2{background-color:#90a4ae!important}.blue-grey-text.text-lighten-2{color:#90a4ae!important}.blue-grey.lighten-1{background-color:#78909c!important}.blue-grey-text.text-lighten-1{color:#78909c!important}.blue-grey.darken-1{background-color:#546e7a!important}.blue-grey-text.text-darken-1{color:#546e7a!important}.blue-grey.darken-2{background-color:#455a64!important}.blue-grey-text.text-darken-2{color:#455a64!important}.blue-grey.darken-3{background-color:#37474f!important}.blue-grey-text.text-darken-3{color:#37474f!important}.blue-grey.darken-4{background-color:#263238!important}.blue-grey-text.text-darken-4{color:#263238!important}.grey{background-color:#9e9e9e!important}.grey-text{color:#9e9e9e!important}.grey.lighten-5{background-color:#fafafa!important}.grey-text.text-lighten-5{color:#fafafa!important}.grey.lighten-4{background-color:#f5f5f5!important}.grey-text.text-lighten-4{color:#f5f5f5!important}.grey.lighten-3{background-color:#eee!important}.grey-text.text-lighten-3{color:#eee!important}.grey.lighten-2{background-color:#e0e0e0!important}.grey-text.text-lighten-2{color:#e0e0e0!important}.grey.lighten-1{background-color:#bdbdbd!important}.grey-text.text-lighten-1{color:#bdbdbd!important}.grey.darken-1{background-color:#757575!important}.grey-text.text-darken-1{color:#757575!important}.grey.darken-2{background-color:#616161!important}.grey-text.text-darken-2{color:#616161!important}.grey.darken-3{background-color:#424242!important}.grey-text.text-darken-3{color:#424242!important}.grey.darken-4{background-color:#212121!important}.grey-text.text-darken-4{color:#212121!important}.black{background-color:#000!important}.black-text{color:#000!important}.white{background-color:#FFF!important}.white-text{color:#FFF!important}.transparent{background-color:transparent!important}.transparent-text{color:transparent!important} - - body,p{color:#8a8a8a;font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif}.font-primary,body,p{font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif}label,ul{margin-bottom:0}dd,p{margin-bottom:10px}.m-h-0,.m-l-0{margin-left:0!important}.m-h-0,.m-r-0{margin-right:0!important}.p-t-0,.p-v-0{padding-top:0!important}.p-b-0,.p-v-0{padding-bottom:0!important}.p-h-0,.p-r-0{padding-right:0!important}.relative,blockquote{position:relative}.overflow-x-hidden,body{overflow-x:hidden}.header,.side-nav{transition:all .2s ease}.header .header-container:after,.side-nav .side-nav-inner .side-nav-menu:after{clear:both}.pointer,button{cursor:pointer}body,html,html a{-webkit-font-smoothing:antialiased}body{font-size:14px;background-color:#f7fbff;line-height:1.5}h1,h2,h3,h4,h5,h6{color:#515365;font-weight:400;line-height:1.5}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:300;color:#5c5f73}h1{font-size:28px}h2{font-size:24px}h3{font-size:22px}h4{font-size:19px}h5{font-size:17px}h6{font-size:12px}p{line-height:1.8}.lead{font-size:18px}a{color:#04a1f4}a:focus,a:hover{text-decoration:none;color:#0380c2}a:focus{outline:0}a.text-gray:focus,a.text-gray:hover{color:#515365!important}a.text-gray.active{color:#04a1f4!important}a.hover-opacity:hover{opacity:.8}:focus{outline:0}hr{border-top:1px solid #e9eaec;margin-top:2rem;margin-bottom:2rem}.text-link:focus,.text-link:hover{text-decoration:underline}.text-opacity{opacity:.85}.text-white{color:#fff!important}.text-dark{color:#515365!important}.text-gray{color:#8a8a8a!important}.text-secondary{color:#cacaca!important}.text-primary{color:#6569df!important}.text-success{color:#24d5d8!important}.text-info{color:#04a1f4!important}.text-warning{color:#fecd2f!important}.text-danger{color:#fd3259!important}.icon-gradient-primary{color:#6569df}.icon-gradient-primary:before{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-success{color:#24d5d8}.icon-gradient-success:before{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-warning{color:#fecd2f}.icon-gradient-warning:before{background:linear-gradient(120deg,#f6d365 0,#fda085 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-danger{color:#fd3259}.icon-gradient-danger:before{background:linear-gradient(120deg,#f3301a 0,#f37138 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.icon-gradient-info{color:#04a1f4}.blockquote-footer,.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a,.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,dt{color:#515365}.icon-gradient-info:before{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent}.bg-white{background-color:#fff!important}.bg-dark{background-color:#515365!important}.bg-gray{background-color:#fafafa!important}.bg-primary{background-color:#6569df!important}.bg-success{background-color:#24d5d8!important}.bg-info{background-color:#04a1f4!important}.bg-warning{background-color:#fecd2f!important}.bg-danger{background-color:#fd3259!important}.bg-gradient-primary{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)!important}.bg-gradient-success{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)!important}.bg-gradient-info{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)!important}.bg-gradient-warning{background:linear-gradient(120deg,#f6d365 0,#fda085 100%)!important}.bg-gradient-danger{background:linear-gradient(120deg,#f3301a 0,#f37138 100%)!important}.bg-facebook{background-color:#3B579D!important}.bg-twitter{background-color:#2CAAE1!important}.bg-google-plus{background-color:#dc473c!important}.bg-instagram{background-color:#40719b!important}.bg-dropbox{background-color:#007EE6!important}.bg-dribbble{background-color:#ea4c89!important}.bg-behance{background-color:#1869ff!important}.bg-html5{background-color:#f16528!important}.bg-wordpress{background-color:#0087be!important}.bg-tumblr{background-color:#36465d!important}.bg-skype{background-color:#00AAF1!important}.bg-youtube{background-color:#DE2825!important}.bg-vimeo{background-color:#1BB6EC!important}.bg-linkedin{background-color:#0177b5!important}.bg-pinterest{background-color:#c9181f!important}.img-fit-cover{width:100%;height:100%;object-fit:cover}.bg{background-repeat:no-repeat;background-size:cover;background-position:center center}.container-fluid.container-fixed-lg{max-width:1700px}.container-fluid.container-fixed-md{max-width:1400px}.container-fluid.container-fixed-sm{max-width:1280px}button,input,textarea{outline:0}blockquote{border-left:0;padding-left:30px}.p-h-0,.p-l-0{padding-left:0!important}dt{font-weight:500}.m-b-0,.m-v-0{margin-bottom:0!important}.fade.in{opacity:1}.collapse.in{display:block}iframe{border:0}@media print{body{font-size:10px}.mrg-top-20,.mrg-top-30{margin-top:15px!important}.print-invisible{display:none}}.m-t-0,.m-v-0{margin-top:0!important}.m-0{margin:0!important}.m-5{margin:5px!important}.m-10{margin:10px!important}.m-15{margin:15px!important}.m-20{margin:20px!important}.m-25{margin:25px!important}.m-30{margin:30px!important}.m-35{margin:35px!important}.m-40{margin:40px!important}.m-45{margin:45px!important}.m-50{margin:50px!important}.m-55{margin:55px!important}.m-60{margin:60px!important}.m-65{margin:65px!important}.m-70{margin:70px!important}.m-75{margin:75px!important}.m-80{margin:80px!important}.m-85{margin:85px!important}.m-90{margin:90px!important}.m-95{margin:95px!important}.m-100{margin:100px!important}.m-105{margin:105px!important}.m-110{margin:110px!important}.m-115{margin:115px!important}.m-120{margin:120px!important}.m-125{margin:125px!important}.m-130{margin:130px!important}.m-135{margin:135px!important}.m-140{margin:140px!important}.m-145{margin:145px!important}.m-150{margin:150px!important}@media only screen and (max-width:767px){iframe{min-height:175px!important;height:auto}.m-100,.m-110,.m-115,.m-120,.m-125,.m-130,.m-135,.m-140,.m-145,.m-150,.m-35,.m-40,.m-45,.m-50,.m-55,.m-60,.m-65,.m-70,.m-75,.m-80,.m-85,.m-90,.m-95{margin:30px!important}}.m-h-auto,.m-l-auto{margin-left:auto!important}.m-h-auto,.m-r-auto{margin-right:auto!important}.m-v-5{margin-top:5px!important;margin-bottom:5px!important}.m-v-10{margin-top:10px!important;margin-bottom:10px!important}.m-v-15{margin-top:15px!important;margin-bottom:15px!important}.m-v-20{margin-top:20px!important;margin-bottom:20px!important}.m-v-25{margin-top:25px!important;margin-bottom:25px!important}.m-v-30{margin-top:30px!important;margin-bottom:30px!important}.m-v-35{margin-top:35px!important;margin-bottom:35px!important}.m-v-40{margin-top:40px!important;margin-bottom:40px!important}.m-v-45{margin-top:45px!important;margin-bottom:45px!important}.m-v-50{margin-top:50px!important;margin-bottom:50px!important}.m-v-55{margin-top:55px!important;margin-bottom:55px!important}.m-v-60{margin-top:60px!important;margin-bottom:60px!important}.m-v-65{margin-top:65px!important;margin-bottom:65px!important}.m-v-70{margin-top:70px!important;margin-bottom:70px!important}.m-v-75{margin-top:75px!important;margin-bottom:75px!important}.m-v-80{margin-top:80px!important;margin-bottom:80px!important}.m-v-85{margin-top:85px!important;margin-bottom:85px!important}.m-v-90{margin-top:90px!important;margin-bottom:90px!important}.m-v-95{margin-top:95px!important;margin-bottom:95px!important}.m-v-100{margin-top:100px!important;margin-bottom:100px!important}.m-v-105{margin-top:105px!important;margin-bottom:105px!important}.m-v-110{margin-top:110px!important;margin-bottom:110px!important}.m-v-115{margin-top:115px!important;margin-bottom:115px!important}.m-v-120{margin-top:120px!important;margin-bottom:120px!important}.m-v-125{margin-top:125px!important;margin-bottom:125px!important}.m-v-130{margin-top:130px!important;margin-bottom:130px!important}.m-v-135{margin-top:135px!important;margin-bottom:135px!important}.m-v-140{margin-top:140px!important;margin-bottom:140px!important}.m-v-145{margin-top:145px!important;margin-bottom:145px!important}.m-v-150{margin-top:150px!important;margin-bottom:150px!important}.m-h-5{margin-left:5px!important;margin-right:5px!important}.m-h-10{margin-left:10px!important;margin-right:10px!important}.m-h-15{margin-left:15px!important;margin-right:15px!important}.m-h-20{margin-left:20px!important;margin-right:20px!important}.m-h-25{margin-left:25px!important;margin-right:25px!important}.m-h-30{margin-left:30px!important;margin-right:30px!important}.m-h-35{margin-left:35px!important;margin-right:35px!important}.m-h-40{margin-left:40px!important;margin-right:40px!important}.m-h-45{margin-left:45px!important;margin-right:45px!important}.m-h-50{margin-left:50px!important;margin-right:50px!important}.m-h-55{margin-left:55px!important;margin-right:55px!important}.m-h-60{margin-left:60px!important;margin-right:60px!important}.m-h-65{margin-left:65px!important;margin-right:65px!important}.m-h-70{margin-left:70px!important;margin-right:70px!important}.m-h-75{margin-left:75px!important;margin-right:75px!important}.m-h-80{margin-left:80px!important;margin-right:80px!important}.m-h-85{margin-left:85px!important;margin-right:85px!important}.m-h-90{margin-left:90px!important;margin-right:90px!important}.m-h-95{margin-left:95px!important;margin-right:95px!important}.m-h-100{margin-left:100px!important;margin-right:100px!important}.m-h-105{margin-left:105px!important;margin-right:105px!important}.m-h-110{margin-left:110px!important;margin-right:110px!important}.m-h-115{margin-left:115px!important;margin-right:115px!important}.m-h-120{margin-left:120px!important;margin-right:120px!important}.m-h-125{margin-left:125px!important;margin-right:125px!important}.m-h-130{margin-left:130px!important;margin-right:130px!important}.m-h-135{margin-left:135px!important;margin-right:135px!important}.m-h-140{margin-left:140px!important;margin-right:140px!important}.m-h-145{margin-left:145px!important;margin-right:145px!important}.m-h-150{margin-left:150px!important;margin-right:150px!important}@media only screen and (max-width:767px){.m-v-100,.m-v-110,.m-v-115,.m-v-120,.m-v-125,.m-v-130,.m-v-135,.m-v-140,.m-v-145,.m-v-150,.m-v-35,.m-v-40,.m-v-45,.m-v-50,.m-v-55,.m-v-60,.m-v-65,.m-v-70,.m-v-75,.m-v-80,.m-v-85,.m-v-90,.m-v-95{margin-top:30px!important;margin-bottom:30px!important}.m-h-100,.m-h-110,.m-h-115,.m-h-120,.m-h-125,.m-h-130,.m-h-135,.m-h-140,.m-h-145,.m-h-150,.m-h-35,.m-h-40,.m-h-45,.m-h-50,.m-h-55,.m-h-60,.m-h-65,.m-h-70,.m-h-75,.m-h-80,.m-h-85,.m-h-90,.m-h-95{margin-left:30px!important;margin-right:30px!important}}.m-t-5{margin-top:5px!important}.m-t-10{margin-top:10px!important}.m-t-15{margin-top:15px!important}.m-t-20{margin-top:20px!important}.m-t-25{margin-top:25px!important}.m-t-30{margin-top:30px!important}.m-t-35{margin-top:35px!important}.m-t-40{margin-top:40px!important}.m-t-45{margin-top:45px!important}.m-t-50{margin-top:50px!important}.m-t-55{margin-top:55px!important}.m-t-60{margin-top:60px!important}.m-t-65{margin-top:65px!important}.m-t-70{margin-top:70px!important}.m-t-75{margin-top:75px!important}.m-t-80{margin-top:80px!important}.m-t-85{margin-top:85px!important}.m-t-90{margin-top:90px!important}.m-t-95{margin-top:95px!important}.m-t-100{margin-top:100px!important}.m-t-105{margin-top:105px!important}.m-t-110{margin-top:110px!important}.m-t-115{margin-top:115px!important}.m-t-120{margin-top:120px!important}.m-t-125{margin-top:125px!important}.m-t-130{margin-top:130px!important}.m-t-135{margin-top:135px!important}.m-t-140{margin-top:140px!important}.m-t-145{margin-top:145px!important}.m-t-150{margin-top:150px!important}.m-b-5{margin-bottom:5px!important}.m-b-10{margin-bottom:10px!important}.m-b-15{margin-bottom:15px!important}.m-b-20{margin-bottom:20px!important}.m-b-25{margin-bottom:25px!important}.m-b-30{margin-bottom:30px!important}.m-b-35{margin-bottom:35px!important}.m-b-40{margin-bottom:40px!important}.m-b-45{margin-bottom:45px!important}.m-b-50{margin-bottom:50px!important}.m-b-55{margin-bottom:55px!important}.m-b-60{margin-bottom:60px!important}.m-b-65{margin-bottom:65px!important}.m-b-70{margin-bottom:70px!important}.m-b-75{margin-bottom:75px!important}.m-b-80{margin-bottom:80px!important}.m-b-85{margin-bottom:85px!important}.m-b-90{margin-bottom:90px!important}.m-b-95{margin-bottom:95px!important}.m-b-100{margin-bottom:100px!important}.m-b-105{margin-bottom:105px!important}.m-b-110{margin-bottom:110px!important}.m-b-115{margin-bottom:115px!important}.m-b-120{margin-bottom:120px!important}.m-b-125{margin-bottom:125px!important}.m-b-130{margin-bottom:130px!important}.m-b-135{margin-bottom:135px!important}.m-b-140{margin-bottom:140px!important}.m-b-145{margin-bottom:145px!important}.m-b-150{margin-bottom:150px!important}.m-l-5{margin-left:5px!important}.m-l-10{margin-left:10px!important}.m-l-15{margin-left:15px!important}.m-l-20{margin-left:20px!important}.m-l-25{margin-left:25px!important}.m-l-30{margin-left:30px!important}.m-l-35{margin-left:35px!important}.m-l-40{margin-left:40px!important}.m-l-45{margin-left:45px!important}.m-l-50{margin-left:50px!important}.m-l-55{margin-left:55px!important}.m-l-60{margin-left:60px!important}.m-l-65{margin-left:65px!important}.m-l-70{margin-left:70px!important}.m-l-75{margin-left:75px!important}.m-l-80{margin-left:80px!important}.m-l-85{margin-left:85px!important}.m-l-90{margin-left:90px!important}.m-l-95{margin-left:95px!important}.m-l-100{margin-left:100px!important}.m-l-105{margin-left:105px!important}.m-l-110{margin-left:110px!important}.m-l-115{margin-left:115px!important}.m-l-120{margin-left:120px!important}.m-l-125{margin-left:125px!important}.m-l-130{margin-left:130px!important}.m-l-135{margin-left:135px!important}.m-l-140{margin-left:140px!important}.m-l-145{margin-left:145px!important}.m-l-150{margin-left:150px!important}.m-r-5{margin-right:5px!important}.m-r-10{margin-right:10px!important}.m-r-15{margin-right:15px!important}.m-r-20{margin-right:20px!important}.m-r-25{margin-right:25px!important}.m-r-30{margin-right:30px!important}.m-r-35{margin-right:35px!important}.m-r-40{margin-right:40px!important}.m-r-45{margin-right:45px!important}.m-r-50{margin-right:50px!important}.m-r-55{margin-right:55px!important}.m-r-60{margin-right:60px!important}.m-r-65{margin-right:65px!important}.m-r-70{margin-right:70px!important}.m-r-75{margin-right:75px!important}.m-r-80{margin-right:80px!important}.m-r-85{margin-right:85px!important}.m-r-90{margin-right:90px!important}.m-r-95{margin-right:95px!important}.m-r-100{margin-right:100px!important}.m-r-105{margin-right:105px!important}.m-r-110{margin-right:110px!important}.m-r-115{margin-right:115px!important}.m-r-120{margin-right:120px!important}.m-r-125{margin-right:125px!important}.m-r-130{margin-right:130px!important}.m-r-135{margin-right:135px!important}.m-r-140{margin-right:140px!important}.m-r-145{margin-right:145px!important}.m-r-150{margin-right:150px!important}.p-0{padding:0!important}.p-5{padding:5px!important}.p-10{padding:10px!important}.p-15{padding:15px!important}.p-20{padding:20px!important}.p-25{padding:25px!important}.p-30{padding:30px!important}.p-35{padding:35px!important}.p-40{padding:40px!important}.p-45{padding:45px!important}.p-50{padding:50px!important}.p-55{padding:55px!important}.p-60{padding:60px!important}.p-65{padding:65px!important}.p-70{padding:70px!important}.p-75{padding:75px!important}.p-80{padding:80px!important}.p-85{padding:85px!important}.p-90{padding:90px!important}.p-95{padding:95px!important}.p-100{padding:100px!important}.p-105{padding:105px!important}.p-110{padding:110px!important}.p-115{padding:115px!important}.p-120{padding:120px!important}.p-125{padding:125px!important}.p-130{padding:130px!important}.p-135{padding:135px!important}.p-140{padding:140px!important}.p-145{padding:145px!important}.p-150{padding:150px!important}@media only screen and (max-width:767px){.m-t-100,.m-t-110,.m-t-115,.m-t-120,.m-t-125,.m-t-130,.m-t-135,.m-t-140,.m-t-145,.m-t-150,.m-t-35,.m-t-40,.m-t-45,.m-t-50,.m-t-55,.m-t-60,.m-t-65,.m-t-70,.m-t-75,.m-t-80,.m-t-85,.m-t-90,.m-t-95{margin-top:30px!important}.m-b-100,.m-b-110,.m-b-115,.m-b-120,.m-b-125,.m-b-130,.m-b-135,.m-b-140,.m-b-145,.m-b-150,.m-b-35,.m-b-40,.m-b-45,.m-b-50,.m-b-55,.m-b-60,.m-b-65,.m-b-70,.m-b-75,.m-b-80,.m-b-85,.m-b-90,.m-b-95{margin-bottom:30px!important}.m-l-100,.m-l-110,.m-l-115,.m-l-120,.m-l-125,.m-l-130,.m-l-135,.m-l-140,.m-l-145,.m-l-150,.m-l-35,.m-l-40,.m-l-45,.m-l-50,.m-l-55,.m-l-60,.m-l-65,.m-l-70,.m-l-75,.m-l-80,.m-l-85,.m-l-90,.m-l-95{margin-left:30px!important}.m-r-100,.m-r-110,.m-r-115,.m-r-120,.m-r-125,.m-r-130,.m-r-135,.m-r-140,.m-r-145,.m-r-150,.m-r-35,.m-r-40,.m-r-45,.m-r-50,.m-r-55,.m-r-60,.m-r-65,.m-r-70,.m-r-75,.m-r-80,.m-r-85,.m-r-90,.m-r-95{margin-right:30px!important}.p-100,.p-110,.p-115,.p-120,.p-125,.p-130,.p-135,.p-140,.p-145,.p-150,.p-35,.p-40,.p-45,.p-50,.p-55,.p-60,.p-65,.p-70,.p-75,.p-80,.p-85,.p-90,.p-95{padding:30px!important}}.p-v-5{padding-top:5px!important;padding-bottom:5px!important}.p-v-10{padding-top:10px!important;padding-bottom:10px!important}.p-v-15{padding-top:15px!important;padding-bottom:15px!important}.p-v-20{padding-top:20px!important;padding-bottom:20px!important}.p-v-25{padding-top:25px!important;padding-bottom:25px!important}.p-v-30{padding-top:30px!important;padding-bottom:30px!important}.p-v-35{padding-top:35px!important;padding-bottom:35px!important}.p-v-40{padding-top:40px!important;padding-bottom:40px!important}.p-v-45{padding-top:45px!important;padding-bottom:45px!important}.p-v-50{padding-top:50px!important;padding-bottom:50px!important}.p-v-55{padding-top:55px!important;padding-bottom:55px!important}.p-v-60{padding-top:60px!important;padding-bottom:60px!important}.p-v-65{padding-top:65px!important;padding-bottom:65px!important}.p-v-70{padding-top:70px!important;padding-bottom:70px!important}.p-v-75{padding-top:75px!important;padding-bottom:75px!important}.p-v-80{padding-top:80px!important;padding-bottom:80px!important}.p-v-85{padding-top:85px!important;padding-bottom:85px!important}.p-v-90{padding-top:90px!important;padding-bottom:90px!important}.p-v-95{padding-top:95px!important;padding-bottom:95px!important}.p-v-100{padding-top:100px!important;padding-bottom:100px!important}.p-v-105{padding-top:105px!important;padding-bottom:105px!important}.p-v-110{padding-top:110px!important;padding-bottom:110px!important}.p-v-115{padding-top:115px!important;padding-bottom:115px!important}.p-v-120{padding-top:120px!important;padding-bottom:120px!important}.p-v-125{padding-top:125px!important;padding-bottom:125px!important}.p-v-130{padding-top:130px!important;padding-bottom:130px!important}.p-v-135{padding-top:135px!important;padding-bottom:135px!important}.p-v-140{padding-top:140px!important;padding-bottom:140px!important}.p-v-145{padding-top:145px!important;padding-bottom:145px!important}.p-v-150{padding-top:150px!important;padding-bottom:150px!important}.p-h-5{padding-left:5px!important;padding-right:5px!important}.p-h-10{padding-left:10px!important;padding-right:10px!important}.p-h-15{padding-left:15px!important;padding-right:15px!important}.p-h-20{padding-left:20px!important;padding-right:20px!important}.p-h-25{padding-left:25px!important;padding-right:25px!important}.p-h-30{padding-left:30px!important;padding-right:30px!important}.p-h-35{padding-left:35px!important;padding-right:35px!important}.p-h-40{padding-left:40px!important;padding-right:40px!important}.p-h-45{padding-left:45px!important;padding-right:45px!important}.p-h-50{padding-left:50px!important;padding-right:50px!important}.p-h-55{padding-left:55px!important;padding-right:55px!important}.p-h-60{padding-left:60px!important;padding-right:60px!important}.p-h-65{padding-left:65px!important;padding-right:65px!important}.p-h-70{padding-left:70px!important;padding-right:70px!important}.p-h-75{padding-left:75px!important;padding-right:75px!important}.p-h-80{padding-left:80px!important;padding-right:80px!important}.p-h-85{padding-left:85px!important;padding-right:85px!important}.p-h-90{padding-left:90px!important;padding-right:90px!important}.p-h-95{padding-left:95px!important;padding-right:95px!important}.p-h-100{padding-left:100px!important;padding-right:100px!important}.p-h-105{padding-left:105px!important;padding-right:105px!important}.p-h-110{padding-left:110px!important;padding-right:110px!important}.p-h-115{padding-left:115px!important;padding-right:115px!important}.p-h-120{padding-left:120px!important;padding-right:120px!important}.p-h-125{padding-left:125px!important;padding-right:125px!important}.p-h-130{padding-left:130px!important;padding-right:130px!important}.p-h-135{padding-left:135px!important;padding-right:135px!important}.p-h-140{padding-left:140px!important;padding-right:140px!important}.p-h-145{padding-left:145px!important;padding-right:145px!important}.p-h-150{padding-left:150px!important;padding-right:150px!important}@media only screen and (max-width:767px){.p-v-100,.p-v-110,.p-v-115,.p-v-120,.p-v-125,.p-v-130,.p-v-135,.p-v-140,.p-v-145,.p-v-150,.p-v-35,.p-v-40,.p-v-45,.p-v-50,.p-v-55,.p-v-60,.p-v-65,.p-v-70,.p-v-75,.p-v-80,.p-v-85,.p-v-90,.p-v-95{padding-top:30px!important;padding-bottom:30px!important}.p-h-100,.p-h-110,.p-h-115,.p-h-120,.p-h-125,.p-h-130,.p-h-135,.p-h-140,.p-h-145,.p-h-150,.p-h-35,.p-h-40,.p-h-45,.p-h-50,.p-h-55,.p-h-60,.p-h-65,.p-h-70,.p-h-75,.p-h-80,.p-h-85,.p-h-90,.p-h-95{padding-left:30px!important;padding-right:30px!important}}.p-t-5{padding-top:5px!important}.p-t-10{padding-top:10px!important}.p-t-15{padding-top:15px!important}.p-t-20{padding-top:20px!important}.p-t-25{padding-top:25px!important}.p-t-30{padding-top:30px!important}.p-t-35{padding-top:35px!important}.p-t-40{padding-top:40px!important}.p-t-45{padding-top:45px!important}.p-t-50{padding-top:50px!important}.p-t-55{margin-top:55px!important}.p-t-60{padding-top:60px!important}.p-t-65{padding-top:65px!important}.p-t-70{padding-top:70px!important}.p-t-75{padding-top:75px!important}.p-t-80{padding-top:80px!important}.p-t-85{padding-top:85px!important}.p-t-90{padding-top:90px!important}.p-t-95{padding-top:95px!important}.p-t-100{padding-top:100px!important}.p-t-105{padding-top:105px!important}.p-t-110{padding-top:110px!important}.p-t-115{padding-top:115px!important}.p-t-120{padding-top:120px!important}.p-t-125{padding-top:125px!important}.p-t-130{padding-top:130px!important}.p-t-135{padding-top:135px!important}.p-t-140{padding-top:140px!important}.p-t-145{padding-top:145px!important}.p-t-150{padding-top:150px!important}.p-b-5{padding-bottom:5px!important}.p-b-10{padding-bottom:10px!important}.p-b-15{padding-bottom:15px!important}.p-b-20{padding-bottom:20px!important}.p-b-25{padding-bottom:25px!important}.p-b-30{padding-bottom:30px!important}.p-b-35{padding-bottom:35px!important}.p-b-40{padding-bottom:40px!important}.p-b-45{padding-bottom:45px!important}.p-b-50{padding-bottom:50px!important}.p-b-55{margin-bottom:55px!important}.p-b-60{padding-bottom:60px!important}.p-b-65{padding-bottom:65px!important}.p-b-70{padding-bottom:70px!important}.p-b-75{padding-bottom:75px!important}.p-b-80{padding-bottom:80px!important}.p-b-85{padding-bottom:85px!important}.p-b-90{padding-bottom:90px!important}.p-b-95{padding-bottom:95px!important}.p-b-100{padding-bottom:100px!important}.p-b-105{padding-bottom:105px!important}.p-b-110{padding-bottom:110px!important}.p-b-115{padding-bottom:115px!important}.p-b-120{margin-bottom:120px!important}.p-b-125{padding-bottom:125px!important}.p-b-130{padding-bottom:130px!important}.p-b-135{padding-bottom:135px!important}.p-b-140{padding-bottom:140px!important}.p-b-145{padding-bottom:145px!important}.p-b-150{padding-bottom:150px!important}.p-l-5{padding-left:5px!important}.p-l-10{padding-left:10px!important}.p-l-15{padding-left:15px!important}.p-l-20{padding-left:20px!important}.p-l-25{padding-left:25px!important}.p-l-30{padding-left:30px!important}.p-l-35{padding-left:35px!important}.p-l-40{padding-left:40px!important}.p-l-45{padding-left:45px!important}.p-l-50{padding-left:50px!important}.p-l-55{margin-left:55px!important}.p-l-60{padding-left:60px!important}.p-l-65{padding-left:65px!important}.p-l-70{padding-left:70px!important}.p-l-75{padding-left:75px!important}.p-l-80{padding-left:80px!important}.p-l-85{padding-left:85px!important}.p-l-90{padding-left:90px!important}.p-l-95{padding-left:95px!important}.p-l-100{padding-left:100px!important}.p-l-105{padding-left:105px!important}.p-l-115{padding-left:115px!important}.p-l-120{margin-left:120px!important}.p-l-125{padding-left:125px!important}.p-l-130{padding-left:130px!important}.p-l-135{padding-left:135px!important}.p-l-140{padding-left:140px!important}.p-l-145{padding-left:145px!important}.p-l-150{padding-left:150px!important}@media only screen and (max-width:767px){.p-t-100,.p-t-110,.p-t-115,.p-t-120,.p-t-125,.p-t-130,.p-t-135,.p-t-140,.p-t-145,.p-t-150,.p-t-35,.p-t-40,.p-t-45,.p-t-50,.p-t-55,.p-t-60,.p-t-65,.p-t-70,.p-t-75,.p-t-80,.p-t-85,.p-t-90,.p-t-95{padding-top:30px!important}.p-b-100,.p-b-110,.p-b-115,.p-b-120,.p-b-125,.p-b-130,.p-b-135,.p-b-140,.p-b-145,.p-b-150,.p-b-35,.p-b-40,.p-b-45,.p-b-50,.p-b-55,.p-b-60,.p-b-65,.p-b-70,.p-b-75,.p-b-80,.p-b-85,.p-b-90,.p-b-95{padding-bottom:30px!important}.p-l-100,.p-l-110,.p-l-115,.p-l-120,.p-l-125,.p-l-130,.p-l-135,.p-l-140,.p-l-145,.p-l-150,.p-l-35,.p-l-40,.p-l-45,.p-l-50,.p-l-55,.p-l-60,.p-l-65,.p-l-70,.p-l-75,.p-l-80,.p-l-85,.p-l-90,.p-l-95{padding-left:30px!important}}.p-r-5{padding-right:5px!important}.p-r-10{padding-right:10px!important}.p-r-15{padding-right:15px!important}.p-r-20{padding-right:20px!important}.p-r-25{padding-right:25px!important}.p-r-30{padding-right:30px!important}.p-r-35{padding-right:35px!important}.p-r-40{padding-right:40px!important}.p-r-45{padding-right:45px!important}.p-r-50{padding-right:50px!important}.p-r-55{margin-right:55px!important}.p-r-60{padding-right:60px!important}.p-r-65{padding-right:65px!important}.p-r-70{padding-right:70px!important}.p-r-75{padding-right:75px!important}.p-r-80{padding-right:80px!important}.p-r-85{padding-right:85px!important}.p-r-90{padding-right:90px!important}.p-r-95{padding-right:95px!important}.p-r-100{padding-right:100px!important}.p-r-105{padding-right:105px!important}.p-l-110{padding-left:110px!important}.p-r-115{padding-right:115px!important}.p-r-120{margin-right:120px!important}.p-r-125{padding-right:125px!important}.p-r-130{padding-right:130px!important}.p-r-135{padding-right:135px!important}.p-r-140{padding-right:140px!important}.p-r-145{padding-right:145px!important}.p-r-150{padding-right:150px!important}.width-0{width:0}.width-10{width:10%}.width-15{width:15%}.width-20{width:20%}.width-25{width:25%}.width-30{width:30%}.width-35{width:35%}.width-40{width:40%}.width-45{width:45%}.width-50{width:50%}.width-55{width:55%}.width-60{width:60%}.width-65{width:65%}.width-70{width:70%}.width-75{width:75%}.width-80{width:80%}.width-85{width:85%}.width-90{width:90%}.width-95{width:95%}.width-100{width:100%}.height-max{height:100%}.full-height{min-height:100vh}.ls-0{letter-spacing:0!important}.ls-0-5{letter-spacing:.5px!important}.ls-1{letter-spacing:1px!important}.ls-1-5{letter-spacing:1.5px!important}.ls-2{letter-spacing:2px!important}.ls-2-5{letter-spacing:2.5px!important}.ls-3{letter-spacing:3px!important}.ls-3-5{letter-spacing:3.5px!important}.ls-4{letter-spacing:4px!important}.ls-4-5{letter-spacing:4.5px!important}.ls-5{letter-spacing:5px!important}.ls-5-5{letter-spacing:5.5px!important}.ls-6{letter-spacing:6px!important}.ls-6-5{letter-spacing:6.5px!important}.ls-7{letter-spacing:7px!important}.ls-7-5{letter-spacing:7.5px!important}.ls-8{letter-spacing:8px!important}.ls-8-5{letter-spacing:8.5px!important}.ls-9{letter-spacing:9px!important}.ls-9-5{letter-spacing:9.5px!important}.ls-10{letter-spacing:10px!important}.ls-11{letter-spacing:11px!important}.ls-12{letter-spacing:12px!important}.ls-13{letter-spacing:13px!important}.ls-14{letter-spacing:14px!important}.ls-15{letter-spacing:15px!important}.lh-0{line-height:0!important}.lh-0-5{line-height:.5!important}.lh-1{line-height:1!important}.lh-1-1{line-height:1.1!important}.lh-1-2{line-height:1.2!important}.lh-1-3{line-height:1.3!important}.lh-1-4{line-height:1.4!important}.lh-1-5{line-height:1.5!important}.lh-1-6{line-height:1.6!important}.lh-1-7{line-height:1.7!important}.lh-1-8{line-height:1.8!important}.lh-1-9{line-height:1.9!important}.lh-2{line-height:2!important}.lh-2-1{line-height:2.1!important}.lh-2-2{line-height:2.2!important}.lh-2-3{line-height:2.3!important}.lh-2-4{line-height:2.4!important}.lh-2-5{line-height:2.5!important}.lh-3{line-height:3!important}.lh-4{line-height:4!important}.font-size-8{font-size:8px!important}.font-size-9{font-size:9px!important}.font-size-10{font-size:10px!important}.font-size-11{font-size:11px!important}.font-size-12{font-size:12px!important}.font-size-13{font-size:13px!important}.font-size-14{font-size:14px!important}.font-size-15{font-size:15px!important}.font-size-16{font-size:16px!important}.font-size-17{font-size:17px!important}.font-size-18{font-size:18px!important}.font-size-19{font-size:19px!important}.font-size-20{font-size:20px!important}.font-size-21{font-size:21px!important}.font-size-22{font-size:22px!important}.font-size-23{font-size:23px!important}.font-size-24{font-size:24px!important}.font-size-25{font-size:25px!important}.font-size-26{font-size:26px!important}.font-size-27{font-size:27px!important}.font-size-28{font-size:28px!important}.font-size-29{font-size:29px!important}.font-size-30{font-size:30px!important}.font-size-35{font-size:35px!important}.font-size-40{font-size:40px!important}.font-size-45{font-size:45px!important}.font-size-50{font-size:50px!important}.font-size-55{font-size:55px!important}.font-size-60{font-size:60px!important}.font-size-65{font-size:65px!important}.font-size-70{font-size:70px!important}.font-size-75{font-size:75px!important}.font-size-80{font-size:80px!important}.font-size-85{font-size:85px!important}.font-size-90{font-size:90px!important}.font-size-95{font-size:95px!important}.font-size-100{font-size:100px!important}.font-size-105{font-size:105px!important}.font-size-110{font-size:110px!important}.font-size-115{font-size:115px!important}.font-size-120{font-size:120px!important}.font-size-125{font-size:125px!important}.font-size-130{font-size:130px!important}.font-size-135{font-size:135px!important}.font-size-140{font-size:140px!important}.font-size-145{font-size:145px!important}.font-size-150{font-size:150px!important}.font-size-155{font-size:155px!important}.font-size-160{font-size:160px!important}.font-size-165{font-size:165px!important}.font-size-170{font-size:170px!important}.font-size-175{font-size:175px!important}.font-size-180{font-size:180px!important}.font-size-185{font-size:185px!important}.font-size-190{font-size:190px!important}.font-size-195{font-size:195px!important}.font-size-200{font-size:200px!important}.text-thin{font-weight:300!important}.text-normal{font-weight:400!important}.text-semibold{font-weight:500!important}.text-bold{font-weight:700!important}.display-block{display:block!important}.inline-block{display:inline-block!important}.absolute{position:absolute}.fixed{position:fixed}.static{position:static}.overflow-hidden{overflow:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-auto{overflow:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-auto{overflow-x:auto}.img-circle{border-radius:50%!important}.border{border:1px solid #e9eaec}.border.top{border:0!important;border-top:1px solid #e9eaec!important}.border.right{border:0!important;border-right:1px solid #e9eaec!important}.border.bottom{border:0!important;border-bottom:1px solid #e9eaec!important}.border.left{border:0!important;border-left:1px solid #e9eaec!important}@media only screen and (max-width:992px){.border.border-hide-md{border-top:0!important;border-right:0!important;border-bottom:0!important;border-left:0!important}}.no-border{border:0!important;border-radius:0!important}.rounded{border-radius:8px!important}.vertical-align{display:table;height:100%;width:100%}.vertical-align .table-cell{display:table-cell;vertical-align:middle}.vertical-align-super{vertical-align:super}.border-radius-4{border-radius:4px!important}.border-radius-6{border-radius:6px!important}.border-radius-8{border-radius:8px!important}.border-radius-10{border-radius:10px!important}.border-radius-round{border-radius:50px!important}.opacity-01{opacity:.1}.opacity-02{opacity:.2}.opacity-03{opacity:.3}.opacity-04{opacity:.4}.opacity-05{opacity:.5}.opacity-06{opacity:.6}.opacity-07{opacity:.7}.opacity-08{opacity:.8}.opacity-09{opacity:.9}.opacity-10{opacity:1}@media only screen and (max-width:767px){.p-r-100,.p-r-110,.p-r-115,.p-r-120,.p-r-125,.p-r-130,.p-r-135,.p-r-140,.p-r-145,.p-r-150,.p-r-35,.p-r-40,.p-r-45,.p-r-50,.p-r-55,.p-r-60,.p-r-65,.p-r-70,.p-r-75,.p-r-80,.p-r-85,.p-r-90,.p-r-95{padding-right:30px!important}.pull-left-sm{float:left!important}.pull-right-sm{float:right!important}.pull-none-sm{float:none!important}.border.border-hide-sm{border-top:0!important;border-right:0!important;border-bottom:0!important;border-left:0!important}.font-size-100,.font-size-105,.font-size-110,.font-size-115,.font-size-120,.font-size-125,.font-size-130,.font-size-135,.font-size-140,.font-size-145,.font-size-50,.font-size-55,.font-size-60,.font-size-65,.font-size-70,.font-size-75,.font-size-80,.font-size-85,.font-size-90,.font-size-95{font-size:45px!important}.font-size-150,.font-size-155,.font-size-160,.font-size-165,.font-size-170,.font-size-175,.font-size-180,.font-size-185,.font-size-190,.font-size-195,.font-size-200{font-size:130px!important}input.width-10,input.width-15,input.width-20,input.width-25,input.width-30,input.width-35,input.width-40,input.width-45,input.width-50,input.width-55,input.width-60,input.width-65,input.width-70,input.width-75,input.width-80,input.width-85,input.width-90,input.width-95,p.width-10,p.width-15,p.width-20,p.width-25,p.width-30,p.width-35,p.width-40,p.width-45,p.width-50,p.width-55,p.width-60,p.width-65,p.width-70,p.width-75,p.width-80,p.width-85,p.width-90,p.width-95{width:100%!important}.side-nav{left:-200px}}.side-nav{width:200px;background-color:#fff;z-index:1000;top:65px;bottom:0;position:fixed;overflow:hidden;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}@media print{.side-nav{display:none}}.side-nav .side-nav-inner{position:relative;height:100%}.side-nav .side-nav-inner .side-nav-menu{position:relative;list-style:none;margin:0;padding-left:0;padding-top:20px;overflow:auto;border-right:1px solid #e9eaec;height:calc(100vh - 65px)}.side-nav .side-nav-inner .side-nav-menu:after,.side-nav .side-nav-inner .side-nav-menu:before{content:" ";display:table}.side-nav .side-nav-inner .side-nav-menu li{position:relative;display:block}.side-nav .side-nav-inner .side-nav-menu li.dropdown .arrow{position:absolute;right:30px;line-height:30px;transition:all 50ms ease-in;-webkit-transition:all 50ms ease-in;-moz-transition:all 50ms ease-in;-o-transition:all 50ms ease-in;-ms-transition:all 50ms ease-in}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a>.arrow{transform:rotate(90deg);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-o-transform:rotate(90deg);-ms-transform:rotate(90deg)}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>.dropdown-menu{display:block}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>.dropdown-menu .dropdown-menu{padding-left:20px}.side-nav .side-nav-inner .side-nav-menu li.dropdown.open>.dropdown-menu .arrow{line-height:25px}.side-nav .side-nav-inner .side-nav-menu li a{color:#8a8a8a;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-o-transition:all .3s ease;-ms-transition:all .3s ease}.side-nav .side-nav-inner .side-nav-menu li a:focus,.side-nav .side-nav-inner .side-nav-menu li a:hover{text-decoration:none;color:#515365}.side-nav .side-nav-inner .side-nav-menu li a:focus .icon-holder,.side-nav .side-nav-inner .side-nav-menu li a:hover .icon-holder{color:#515365}.side-nav .side-nav-inner .side-nav-menu li a.dropdown-toggle:after{display:none;border-radius:0}.side-nav .side-nav-inner .side-nav-menu>li.side-nav-header{text-transform:uppercase;font-size:11px;padding:10px 20px;opacity:.7;margin-top:15px}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu{position:relative;width:100%;box-shadow:none;border:0;border-radius:0;padding-left:50px;padding-top:0;background-color:transparent;float:none}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a{padding:10px 15px}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:focus,.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:hover{background-color:transparent;color:#515365}.side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li.active a{color:#515365}.side-nav .side-nav-inner .side-nav-menu>li>a{position:relative;display:block;padding:10px 15px;font-weight:500;font-size:15px;white-space:nowrap}.side-nav .side-nav-inner .side-nav-menu>li>a .icon-holder{display:inline-block;height:25px;width:25px;line-height:25px;text-align:center;position:relative;left:0;margin-right:14px;font-size:20px;border-radius:6px;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-o-transition:all .3s ease;-ms-transition:all .3s ease}@media only screen and (min-width:992px){.side-nav-folded .side-nav .side-nav-inner .side-nav-menu>li.side-nav-header,.side-nav-folded .side-nav .side-nav-inner .side-nav-menu>li>a .title{display:none}.side-nav-folded .side-nav{width:70px}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu{overflow-x:hidden}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu>li>a{padding-left:20px}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu li.dropdown .arrow{opacity:0}.side-nav-folded .side-nav .side-nav-inner .side-nav-menu li.dropdown.open ul.dropdown-menu{display:none!important}.side-nav-folded .side-nav:hover{width:200px;background:#fff;z-index:9999}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu>li.side-nav-header{display:block}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu>li>a .title{display:inline-block}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu li.dropdown .arrow{opacity:1}.side-nav-folded .side-nav:hover .side-nav-inner .side-nav-menu li.open>ul.dropdown-menu{display:block!important}}@media only screen and (max-width:992px){.side-nav .side-nav-inner .side-nav-menu li.dropdown .arrow{right:25px}.side-nav-folded .side-nav{left:-200px}}.side-nav-folded .header .header-container .nav-logo{width:70px;padding:0}@media only screen and (max-width:767px){.side-nav-folded .header .header-container .nav-logo{width:0;overflow:hidden}.side-nav-expand{overflow:hidden}}.side-nav-folded .header .header-container .nav-logo>a .logo{width:70px;background-position:center center}.side-nav-folded .header .nav-left>li>a.sidenav-fold-toggler i:before{content:"\F054"}@media only screen and (max-width:767px){.side-nav-expand .side-nav{left:0}.side-nav-expand .header .header-container .nav-logo{width:0}.side-nav-expand .header .header-container .nav-left>li>a.sidenav-expand-toggler i:before{content:"\F04D"}.side-nav-backdrop{position:fixed;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background:#515365;background:rgba(81,83,101,.5)}}.header{display:block;height:65px;width:100%;position:fixed;padding:0;z-index:1040;background-color:#fff;border-bottom:1px solid #e9eaec;margin-bottom:0;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}@media print{.header{display:none}}@media only screen and (max-width:992px){.header{width:100%}}.header .header-container:after,.header .header-container:before{content:" ";display:table}.header .header-container .nav-logo{padding:0 20px;line-height:0;float:left;width:200px;transition:all .2s ease;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}.header .header-container .nav-logo>a{display:inline-block;max-width:200px;width:100%}.header .header-container .nav-logo>a .logo{background-repeat:no-repeat;background-position:center left;display:inline-block;width:100%;min-height:calc(65px - 1px)}.header .header-container .nav-logo>a .logo.logo-white{display:none}@media only screen and (max-width:992px){.header .header-container .nav-logo{width:0;padding:0}}.header .header-container .nav-left,.header .header-container .nav-right{position:relative;list-style:none;padding-left:0;margin-bottom:0}.header .header-container .nav-left>li,.header .header-container .nav-right>li{float:left}.header .header-container .nav-left>li>a,.header .header-container .nav-right>li>a{padding:0 12px;line-height:calc(65px - 3px);min-height:calc(65px - 3px);color:#8a8a8a;display:block;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.header .header-container .nav-left>li>a i,.header .header-container .nav-right>li>a i{font-size:22px}.header .header-container .nav-left>li>a:focus,.header .header-container .nav-left>li>a:hover,.header .header-container .nav-right>li>a:focus,.header .header-container .nav-right>li>a:hover{text-decoration:none;color:#515365}.header .header-container .nav-left>li>a.dropdown-toggle:after,.header .header-container .nav-right>li>a.dropdown-toggle:after{display:none;border-radius:0}@media only screen and (min-width:767px){.header .header-container .nav-left>li>a.sidenav-fold-toggler,.header .header-container .nav-right>li>a.sidenav-fold-toggler{display:block}.header .header-container .nav-left>li>a.sidenav-expand-toggler,.header .header-container .nav-right>li>a.sidenav-expand-toggler{display:none}}.header .header-container .nav-left .user-profile .profile-img,.header .header-container .nav-right .user-profile .profile-img{width:35px;border-radius:50%;margin-top:12px;float:left}@media only screen and (max-width:992px){.header .header-container .nav-left>li>a,.header .header-container .nav-right>li>a{padding:0 10px}.header .header-container .nav-left .user-profile,.header .header-container .nav-right .user-profile{border-right:0;border-left:0}.header .header-container .nav-left .user-profile .profile-img,.header .header-container .nav-right .user-profile .profile-img{width:30px;margin-right:0}}.header .header-container .nav-left .notifications,.header .header-container .nav-right .notifications{position:relative}.header .header-container .nav-left .notifications .counter,.header .header-container .nav-right .notifications .counter{position:absolute;right:6px;top:12px;background-color:#fd3259;color:#fff;padding:3px 5.5px;border-radius:50px;line-height:1;font-size:10px}.header .header-container .nav-left{float:left}.content-footer .footer .go-right,.header .header-container .nav-right{float:right}@media only screen and (max-width:767px){.header .header-container .nav-left>li>a.sidenav-fold-toggler,.header .header-container .nav-right>li>a.sidenav-fold-toggler{display:none}.header .header-container .nav-left>li>a.sidenav-expand-toggler,.header .header-container .nav-right>li>a.sidenav-expand-toggler{display:block}.header .header-container .nav-right .dropdown.dropdown-animated.scale-left .dropdown-menu{right:-40px!important}.header .header-container .search-input input{width:85px}}.header .header-container .search-box .search-icon-close,.header .header-container .search-box.active .search-icon{display:none}.header .header-container .search-box.active .search-icon-close{display:inline-block}.header .header-container .search-input{display:none}.header .header-container .search-input.active{display:inline-block}.header .header-container .search-input input{border:0;box-shadow:none;background-color:transparent;outline:0;height:40px;margin-top:10px;padding:5px;font-size:16px}.header .header-container .search-input input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.5)}.header .header-container .search-input .search-predict{display:none;position:absolute;top:65px;width:350px;min-height:50px;max-height:500px;background-color:#fff;color:#8a8a8a;border-radius:4px;-webkit-box-shadow:0 0 8px 0 rgba(0,0,0,.2);-moz-box-shadow:0 0 8px 0 rgba(0,0,0,.2);box-shadow:0 0 8px 0 rgba(0,0,0,.2)}.header .header-container .search-input .search-predict.active{display:block}.header .header-container .search-input .search-predict .search-wrapper{position:relative;max-height:400px;overflow-y:auto}.header .header-container .search-input .search-footer{border-top:1px solid #e9eaec;text-align:center;padding:15px;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.content-footer{padding:0 30px}.content-footer .footer{padding:20px 0;font-size:90%;border-top:1px solid #e9eaec}@media only screen and (max-width:767px){.header .header-container .search-input .search-predict{left:40px}.content-footer .footer{text-align:center}.content-footer .footer .go-right{float:none;margin-top:15px;display:block}}.page-container{min-height:100vh;padding-left:200px;transition:all .2s ease;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-o-transition:all .2s ease;-ms-transition:all .2s ease}@media print{.page-container{padding-left:0}}@media only screen and (max-width:992px){.page-container{padding-left:0}}.page-container .main-content{padding:calc(65px + 35px) 15px 15px;min-height:calc(100vh - 65px)}.page-container .main-content.full-container{padding:95px 0 0}@media print{.page-container .main-content{padding:10px 0}}@media only screen and (max-width:992px){.page-container .main-content{padding:85px 10px 10px}}.page-container .page-header{margin-bottom:30px}.page-container .page-header .header-title{display:inline-block;font-size:23px;margin-bottom:0;padding-bottom:5px;border-right:1px solid #e9eaec;padding-right:20px;line-height:1}@media only screen and (max-width:767px){.page-container .page-header .header-title{border-right:0;display:block;margin-bottom:15px}}.page-container .page-header .header-sub-title{display:inline-block;padding-left:20px}@media only screen and (max-width:767px){.page-container .page-header .header-sub-title{padding-left:0;display:block}}@media only screen and (min-width:992px){.side-nav-folded .page-container{padding-left:70px}}@media only screen and (max-width:992px){.side-nav-folded .page-container{padding-left:0}}.widget-credit-card{max-width:430px}.side-nav-dark .side-nav{background-color:#223143;color:#99abb4}.side-nav-dark .side-nav .side-nav-logo{border-bottom:1px solid rgba(120,130,140,.3);border-right:1px solid transparent}.side-nav-dark .side-nav .side-nav-logo a .logo.logo-white{display:block}.side-nav-dark .side-nav .side-nav-logo a .logo.logo-dark{display:none}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu{border-right:1px solid transparent}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a{color:#99abb4;font-weight:400}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:focus .arrow,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:focus .icon-holder,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:focus .title,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:hover .arrow,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:hover .icon-holder,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li a:hover .title,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .arrow,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .title,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li.active>a,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:focus,.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu>li>a:hover{color:#fff}.side-nav-dark .side-nav .side-nav-inner .side-nav-menu>li.dropdown ul.dropdown-menu{background:#192532;background:rgba(25,37,50,.5)}.header-primary .header{background-color:#6569df}.header-primary .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-primary .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-primary .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#6569df}.header-info .header{background-color:#04a1f4}.header-info .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-info .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-info .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#04a1f4}.header-success .header{background-color:#2acfd2}.header-success .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-success .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-success .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#24d5d8}.header-warning .header{background-color:#fecd2f}.header-warning .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-warning .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-warning .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#fecd2f}.header-danger .header{background-color:#fd3259}.header-danger .side-nav .side-nav-inner .side-nav-menu li.dropdown.open>a .icon-holder,.header-danger .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:focus .icon-holder,.header-danger .side-nav .side-nav-inner .side-nav-menu li.dropdown>a:hover .icon-holder{color:#fd3259}.header-dark .header{background-color:#334a65}.theme-configurator{position:relative}.color-selector label,.theme-selector label{position:relative;display:inline-block;width:25px;height:25px;margin-right:5px;margin-bottom:5px;border-radius:50%;cursor:pointer}.color-selector input,.theme-selector input{opacity:0}.color-selector input:checked~.theme-color:after,.theme-selector input:checked~.theme-color:after{content:"\e64c";font-family:themify;font-size:12px;font-weight:700;display:block;color:#fff;width:100%;text-align:center;position:absolute;top:50%;transform:translateY(-50%);-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%)}.color-selector input:checked~.theme-color.bg-white:after,.theme-selector input:checked~.theme-color.bg-white:after{color:#515365}.color-selector .theme-color,.theme-selector .theme-color{position:absolute;top:0;left:0;right:0;bottom:0;border-radius:50%}.color-pallet{border:1px solid #e9eaec;min-width:180px;margin-bottom:20px}.color-pallet .box{height:120px}.color-pallet .desc{padding:10px}.alert{padding:15px 20px;border-radius:0}.alert-default{color:#7d7d7d;background-color:#f1f2f3;border-color:#d9dade}.alert-default p{color:#7d7d7d}.alert-default hr{border-color:#e9eaec}.alert-primary,.alert-primary hr{border-color:#cfd0f5}.alert-primary{color:#6569df;background-color:#f0f1fc}.alert-primary p{color:#6569df}.alert-success,.alert-success hr{border-color:#8febec}.alert-success{color:#24d5d8;background-color:#e7fbfb}.alert-success p{color:#24d5d8}.alert-info,.alert-info p{color:#04a1f4}.alert-info,.alert-info hr{border-color:#94d9fd}.alert-info{background-color:#e9f7ff}.alert-warning,.alert-warning hr{border-color:#fedf7b}.alert-warning{color:#fecd2f;background-color:#fffefa}.alert-warning p{color:#fecd2f}.alert-danger,.alert-danger p{color:#fd3259}.alert-danger,.alert-danger hr{border-color:#fecad4}.alert-danger{background-color:#fff7f9}.alert-danger-gradient,.alert-info-gradient,.alert-primary-gradient,.alert-success-gradient,.alert-warning-gradient{color:#fff;border-radius:4px}.alert-primary-gradient{border-color:transparent;background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.alert-success-gradient{border-color:transparent;background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.alert-info-gradient{border-color:transparent;background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.alert-warning-gradient{border-color:transparent;background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.alert-danger-gradient{border-color:transparent;background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.alert-float{border-color:transparent;-webkit-box-shadow:0 7px 20px 2px rgba(9,4,25,.1);-moz-box-shadow:0 7px 20px 2px rgba(9,4,25,.1);box-shadow:0 7px 20px 2px rgba(9,4,25,.1)}.alert-icon{font-size:30px;padding:0 7px}button{outline:0;box-shadow:none}button:focus{outline:0}button.active:focus,button:active:focus{outline:0;box-shadow:none}button.disabled,button:disabled{opacity:.5;cursor:not-allowed}.btn-danger.disabled,.btn-danger:disabled,.btn-info.disabled,.btn-info:disabled,.btn-primary.disabled,.btn-primary:disabled,.btn-success.disabled,.btn-success:disabled,.btn-warning.disabled,.btn-warning:disabled{opacity:.35}.btn{cursor:pointer;font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;font-size:14px;padding:7px 20px;margin-right:5px;margin-bottom:10px;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.modal.modal-fs,.modal.modal-left,.modal.modal-right{padding-right:0!important}.btn.dropdown-toggle,.modal-footer .btn,.modal-header h1,.modal-header h2,.modal-header h3,.modal-header h4,.modal-header h5,.modal-header h6{margin-bottom:0}.btn:focus{outline:0;box-shadow:none}.btn.active:focus,.btn:active:focus{outline:0}.btn-default{color:#515365;background-color:transparent;border-color:#dbdde0}.btn-default.active:focus,.btn-default.active:hover,.btn-default:active,.btn-default:active:focus,.btn-default:active:hover,.btn-default:focus,.btn-default:hover{color:#515365;background-color:#eeeff1;border-color:#eeeff1}.btn-primary{background-color:#6569df;border-color:#6569df;color:#fff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#7a7ee3;border-color:#7a7ee3}.btn-primary.active,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active{background-color:#5054db;border-color:#5054db}.btn-primary.disabled,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary:disabled,.btn-primary:disabled:focus,.btn-primary:disabled:hover,.btn-primary:not([disabled]):not(.disabled).active,.btn-primary:not([disabled]):not(.disabled):active{background-color:#6569df;border-color:#6569df}.btn-primary:not([disabled]):not(.disabled).active:focus,.btn-primary:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-primary.btn-outline{background-color:transparent;color:#6569df;border-color:#6569df}.btn-primary.btn-outline:focus,.btn-primary.btn-outline:hover{background-color:#6569df;color:#fff}.btn-success{background-color:#24d5d8;border-color:#24d5d8;color:#fff}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#38dbde;border-color:#38dbde}.btn-success.active,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active{background-color:#20bfc2;border-color:#20bfc2}.btn-success.disabled,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success:disabled,.btn-success:disabled:focus,.btn-success:disabled:hover,.btn-success:not([disabled]):not(.disabled).active,.btn-success:not([disabled]):not(.disabled):active{background-color:#24d5d8;border-color:#24d5d8}.btn-success:not([disabled]):not(.disabled).active:focus,.btn-success:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-success.btn-outline{background-color:transparent;color:#24d5d8;border-color:#24d5d8}.btn-success.btn-outline:focus,.btn-success.btn-outline:hover{background-color:#24d5d8;color:#fff}.btn-info{background-color:#04a1f4;border-color:#04a1f4;color:#fff}.btn-info:focus,.btn-info:hover{color:#fff;background-color:#16acfb;border-color:#16acfb}.btn-info.active,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active{background-color:#0490db;border-color:#0490db}.btn-info.disabled,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info:disabled,.btn-info:disabled:focus,.btn-info:disabled:hover,.btn-info:not([disabled]):not(.disabled).active,.btn-info:not([disabled]):not(.disabled):active{background-color:#04a1f4;border-color:#04a1f4}.btn-info:not([disabled]):not(.disabled).active:focus,.btn-info:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-info.btn-outline{background-color:transparent;color:#04a1f4;border-color:#04a1f4}.btn-info.btn-outline:focus,.btn-info.btn-outline:hover{background-color:#04a1f4;color:#fff}.btn-warning{background-color:#fecd2f;border-color:#fecd2f;color:#fff}.btn-warning:focus,.btn-warning:hover{color:#fff;background-color:#fed348;border-color:#fed348}.btn-warning.active,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active{background-color:#fec716;border-color:#fec716}.btn-warning.disabled,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning:disabled,.btn-warning:disabled:focus,.btn-warning:disabled:hover,.btn-warning:not([disabled]):not(.disabled).active,.btn-warning:not([disabled]):not(.disabled):active{background-color:#fecd2f;border-color:#fecd2f}.btn-warning:not([disabled]):not(.disabled).active:focus,.btn-warning:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-warning.btn-outline{background-color:transparent;color:#fecd2f;border-color:#fecd2f}.btn-warning.btn-outline:focus,.btn-warning.btn-outline:hover{background-color:#fecd2f;color:#fff}.btn-danger{background-color:#fd3259;border-color:#fd3259;color:#fff}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#fd4b6d;border-color:#fd4b6d}.btn-danger.active,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active{background-color:#fd1945;border-color:#fd1945}.btn-danger.disabled,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger:disabled,.btn-danger:disabled:focus,.btn-danger:disabled:hover,.btn-danger:not([disabled]):not(.disabled).active,.btn-danger:not([disabled]):not(.disabled):active{background-color:#fd3259;border-color:#fd3259}.btn-danger:not([disabled]):not(.disabled).active:focus,.btn-danger:not([disabled]):not(.disabled):active:focus{box-shadow:none}.btn-danger.btn-outline{background-color:transparent;color:#fd3259;border-color:#fd3259}.btn-gradient-danger,.btn-gradient-info,.btn-gradient-primary,.btn-gradient-success,.btn-gradient-warning{border:0;color:#fff}.btn-danger.btn-outline:focus,.btn-danger.btn-outline:hover{background-color:#fd3259;color:#fff}.btn-gradient-primary,.btn-gradient-primary.active,.btn-gradient-primary:active,.btn-gradient-primary:focus,.btn-gradient-primary:hover,.btn-gradient-primary:not([disabled]):not(.disabled).active,.btn-gradient-primary:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.btn-gradient-primary:focus,.btn-gradient-primary:hover{opacity:.7;color:#fff}.btn-gradient-primary.active,.btn-gradient-primary:active{color:#fff}.btn-gradient-primary.disabled:focus,.btn-gradient-primary.disabled:hover{opacity:.5}.btn-gradient-success,.btn-gradient-success.active,.btn-gradient-success:active,.btn-gradient-success:focus,.btn-gradient-success:hover,.btn-gradient-success:not([disabled]):not(.disabled).active,.btn-gradient-success:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.btn-gradient-success:focus,.btn-gradient-success:hover{opacity:.7;color:#fff}.btn-gradient-success.active,.btn-gradient-success:active{color:#fff}.btn-gradient-success.disabled:focus,.btn-gradient-success.disabled:hover{opacity:.5}.btn-gradient-info,.btn-gradient-info.active,.btn-gradient-info:active,.btn-gradient-info:focus,.btn-gradient-info:hover,.btn-gradient-info:not([disabled]):not(.disabled).active,.btn-gradient-info:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.btn-gradient-info:focus,.btn-gradient-info:hover{opacity:.7;color:#fff}.btn-gradient-info.active,.btn-gradient-info:active{color:#fff}.btn-gradient-info.disabled:focus,.btn-gradient-info.disabled:hover{opacity:.5}.btn-gradient-warning,.btn-gradient-warning.active,.btn-gradient-warning:active,.btn-gradient-warning:focus,.btn-gradient-warning:hover,.btn-gradient-warning:not([disabled]):not(.disabled).active,.btn-gradient-warning:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.btn-gradient-warning:focus,.btn-gradient-warning:hover{opacity:.7;color:#fff}.btn-gradient-warning.active,.btn-gradient-warning:active{color:#fff}.btn-gradient-warning.disabled:focus,.btn-gradient-warning.disabled:hover{opacity:.5}.btn-gradient-danger,.btn-gradient-danger.active,.btn-gradient-danger:active,.btn-gradient-danger:focus,.btn-gradient-danger:hover,.btn-gradient-danger:not([disabled]):not(.disabled).active,.btn-gradient-danger:not([disabled]):not(.disabled):active{background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.btn-gradient-danger:focus,.btn-gradient-danger:hover{opacity:.7;color:#fff}.btn-gradient-danger.disabled:focus,.btn-gradient-danger.disabled:hover,.checkbox input[type=checkbox].disabled+label,.checkbox input[type=checkbox]:disabled+label,.radio input[type=radio].disabled+label,.radio input[type=radio]:disabled+label{opacity:.5}.btn-gradient-danger.active,.btn-gradient-danger:active{color:#fff}.show>.dropdown-toggle.btn-primary{background-color:#5054db;border-color:#5054db}.show>.dropdown-toggle.btn-primary:focus,.show>.dropdown-toggle.btn-primary:hover{background-color:#5054db;border-color:#5054db;box-shadow:none}.show>.dropdown-toggle.btn-success{background-color:#20bfc2;border-color:#20bfc2}.show>.dropdown-toggle.btn-success:focus,.show>.dropdown-toggle.btn-success:hover{background-color:#20bfc2;border-color:#20bfc2;box-shadow:none}.show>.dropdown-toggle.btn-info{background-color:#0490db;border-color:#0490db}.show>.dropdown-toggle.btn-info:focus,.show>.dropdown-toggle.btn-info:hover{background-color:#0490db;border-color:#0490db;box-shadow:none}.show>.dropdown-toggle.btn-warning{background-color:#fec716;border-color:#fec716}.show>.dropdown-toggle.btn-warning:focus,.show>.dropdown-toggle.btn-warning:hover{background-color:#fec716;border-color:#fec716;box-shadow:none}.show>.dropdown-toggle.btn-danger{background-color:#fd1945;border-color:#fd1945}.show>.dropdown-toggle.btn-danger:focus,.show>.dropdown-toggle.btn-danger:hover{background-color:#fd1945;border-color:#fd1945;box-shadow:none}.modal .modal-dialog{transition:all .2s ease-out;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;-ms-transition:all .2s ease-out}.modal:not(.modal-fs) .modal-dialog,.modal:not(.modal-left) .modal-dialog,.modal:not(.modal-right) .modal-dialog{transform:translateY(20px);-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-o-transform:translateY(20px);-ms-transform:translateY(20px)}.modal:not(.modal-fs).show .modal-dialog,.modal:not(.modal-left).show .modal-dialog,.modal:not(.modal-right).show .modal-dialog{transform:translateY(0);-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);-ms-transform:translateY(0)}.modal.modal-right .modal-dialog{transform:translateX(100%);-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-o-transform:translateX(100%);-ms-transform:translateX(100%)}.modal.modal-right.show .modal-dialog{transform:translateX(0);-webkit-transform:translateX(0);-moz-transform:translateX(0);-o-transform:translateX(0);-ms-transform:translateX(0)}.modal.modal-left .modal-dialog{transform:translateX(-100%);-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-o-transform:translateX(-100%);-ms-transform:translateX(-100%)}.modal.modal-left.show .modal-dialog{transform:translateX(0);-webkit-transform:translateX(0);-moz-transform:translateX(0);-o-transform:translateX(0);-ms-transform:translateX(0)}.modal.modal-fs .modal-dialog{transform:scale(.7);-webkit-transform:scale(.7);-moz-transform:scale(.7);-o-transform:scale(.7);-ms-transform:scale(.7)}.modal.modal-fs.show .modal-dialog{transform:scale(1);-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);-ms-transform:scale(1)}.modal-header{padding:15px 20px 5px;border-bottom:0}.modal-body,.modal-footer{padding:15px 20px}.modal-footer{border-top:1px solid #e9eaec;text-align:left}.modal-footer .btn+.btn{margin-left:0}.modal-content{position:relative;background-color:#fff;border:0;border-radius:0;outline:0;-webkit-box-shadow:0 16px 24px rgba(43,47,49,.25);-moz-box-shadow:0 16px 24px rgba(43,47,49,.25);box-shadow:0 16px 24px rgba(43,47,49,.25)}.modal-left .modal-dialog,.modal-right .modal-dialog{width:400px;height:100%;margin:0 auto 0 0}@media only screen and (max-width:767px){.modal-left .modal-dialog,.modal-right .modal-dialog{width:calc(100% - 50px)}}.modal-left .modal-dialog .modal-content,.modal-right .modal-dialog .modal-content{height:100%;border-radius:0}.modal-left .modal-dialog .modal-content .side-modal-wrapper,.modal-right .modal-dialog .modal-content .side-modal-wrapper{height:100%;position:relative}.modal-left .modal-dialog .modal-content .modal-footer,.modal-right .modal-dialog .modal-content .modal-footer{position:absolute;bottom:0;width:100%}.modal-right .modal-dialog{margin:0 0 0 auto}.modal-backdrop{z-index:1040;background-color:#515365}.modal-fs .modal-dialog{width:100%;margin:0 auto;height:100%;max-width:none}.list-link,.list-media{margin-bottom:0}.modal-fs .modal-dialog .modal-content{height:100%;border-radius:0;background:#fff;background:rgba(255,255,255,.95)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{background-color:#fafafa;border:1px solid #e9eaec}.modal-fs .modal-close{position:absolute;top:20px;right:20px;padding:7px 10px;border:1px solid #9ea0b1;border-radius:50px;color:#9ea0b1}.list,.list li{position:relative}.modal-fs .modal-close:focus,.modal-fs .modal-close:hover{color:#515365;text-decoration:none;border:1px solid #515365}.list li{padding-bottom:10px}.list.arrow,.list.bullet,.list.dash,.list.star,.list.tick{list-style:none;padding-left:0}.list.arrow>li,.list.bullet>li,.list.dash>li,.list.star>li,.list.tick>li{padding-left:30px}.list.arrow>li:before,.list.bullet>li:before,.list.dash>li:before,.list.star>li:before,.list.tick>li:before{font-family:themify;position:absolute;left:0}.list.tick>li:before{content:"\e64c"}.list.star>li:before{content:"\e60a"}.list.dash>li:before{content:"-"}.list.bullet>li:before{content:"\e724"}.list.arrow>li:before{content:"\e649";font-size:10px;top:4px}.bg-overlay:before,.card-refresh:after,.card-refresh:before,.list-media .media-img .status:before{content:""}.list.decimal{list-style-type:decimal;padding-left:20px}.list.decimal li{padding-left:10px}.list.upper-roman{list-style-type:upper-roman;padding-left:20px}.list.upper-roman li{padding-left:10px}.list.lower-alpha{list-style-type:lower-alpha;padding-left:20px}.list.lower-alpha li{padding-left:10px}.list.bullet-primary>li:before{color:#6569df}.list.bullet-info li:before{color:#04a1f4}.list.bullet-success li:before{color:#24d5d8}.list.bullet-warning li:before{color:#fecd2f}.list.bullet-danger li:before{color:#fd3259}.list.bullet-white li:before{color:#fff}.list.bullet-dark li:before{color:#515365}.list-group-item{border:1px solid #e9eaec}.list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.list-group-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.list-group-item.active{color:#515365}.list-group-item.disabled{color:#9ea0b1}.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#9ea0b1;background-color:transparent;border:1px solid #e9eaec}.list-group-item-action{color:#515365}.list-group-item-action:focus,.list-group-item-action:hover{color:#515365;background-color:#fafafa}.list-media{display:block;position:relative;padding-left:0;list-style:none}.list-media>.list-item{display:block}.list-media>.list-item>a{display:block;position:relative;padding:12px 0}.list-media>.list-item>a:focus,.list-media>.list-item>a:hover{text-decoration:none}.list-media>.list-item.active{background-color:#fafafa}.list-media>.list-item .media-hover:focus,.list-media>.list-item .media-hover:hover{text-decoration:none;background-color:#fafafa}.list-media .media-img{position:relative;float:left}.list-media .media-img .icon-avatar,.list-media .media-img img{line-height:40px;height:40px;width:40px;text-align:center;font-size:17px;border-radius:50px;color:#fff}.list-media .media-img .status{right:0;bottom:0;position:absolute;left:auto;top:auto}.list-media .media-img .status:before{position:absolute;background-color:transparent;width:15px;height:14px;bottom:-5px;right:-6px;border-radius:50px;border:2px solid #fff}.list-media .info{padding-left:55px;min-height:40px;height:auto;position:relative}.list-media .info .title{display:block;color:#515365;line-height:1.5}.list-media .info .title.pdd-top-5{padding-top:7px!important}.list-media .info .sub-title{display:block;font-size:12.5px;color:#adadad;color:rgba(138,138,138,.7);max-width:90%}.list-media .info .float-item{position:absolute;right:0;color:#8a8a8a;top:50%;font-size:12px;transform:translateY(-50%);-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%)}.list-media .info.status{padding-left:0;min-height:auto;height:10px;position:absolute}.list-inline>li{display:inline-block;margin-right:10px}.list-media-horizon{display:inline-block;margin-bottom:0}.list-media-horizon>li{float:left;margin-right:0}.list-media-horizon>li>a img,.list-media-horizon>li>img{width:35px;height:35px;border-radius:100%;overflow:hidden;border:2px solid #fff;display:block}.list-media-horizon>li.all-members{border-radius:100%}.list-media-horizon>li.all-members>a{width:35px;line-height:35px;display:block;text-align:center;border-radius:100%;background-color:#fafafa;color:#8a8a8a}.list-media-horizon>li.add-member>a{border:2px dashed #e9eaec;width:35px;line-height:30px;display:block;text-align:center;border-radius:100%;color:#ced0d4;margin-left:5px}.card-toolbar ul>li,.list-label>li,.status{display:inline-block}.list-link li{padding:10px 0}.list-link li a{color:#8a8a8a}.list-link li a:focus,.list-link li a:hover{color:#515365;text-decoration:none}.list-label{padding-left:0;line-height:0}.list-label>li{height:2px;width:40px;background:#fafafa;border-radius:50px;margin-right:5px}.badge{padding:5px 7px;font-size:80%;font-weight:500;line-height:1}.badge-default{color:#515365;background-color:transparent;border:1px solid #dbdde0}.badge-default[href]:focus,.badge-default[href]:hover{background-color:#f7f7f7;color:#515365}.badge-primary{background-color:#6569df}.badge-primary[href]:focus,.badge-primary[href]:hover{background-color:#7a7ee3}.badge-success{background-color:#24d5d8}.badge-success[href]:focus,.badge-success[href]:hover{background-color:#38dbde}.badge-info{background-color:#04a1f4}.badge-info[href]:focus,.badge-info[href]:hover{background-color:#16acfb}.badge-warning{color:#fff;background-color:#fecd2f}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#fff;background-color:#fed348}.badge-danger{background-color:#fd3259}.badge-danger[href]:focus,.badge-danger[href]:hover{background-color:#fd4b6d}.badge-gradient-primary{color:#fff;background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.badge-gradient-success{color:#fff;background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.badge-gradient-info{color:#fff;background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.badge-gradient-warning{color:#fff;background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.badge-gradient-danger{color:#fff;background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.badge-xl{padding:9px 15px;font-size:100%}.badge-lg{padding:8px 13px;font-size:90%}.badge-sm{padding:3px 5px;font-size:75%}.status{width:10px;height:10px;background-color:#fff;border-radius:50px;border:3px solid #c0c3c9}.status.primary{border-color:#6569df}.status.info{border-color:#04a1f4}.status.online,.status.success{border-color:#24d5d8}.status.busy,.status.danger{border-color:#fd3259}.status.away,.status.warning{border-color:#fecd2f}.status.gradient{border:0;background:#fafafa}.status.gradient.primary{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%)}.status.gradient.info{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%)}.status.gradient.online,.status.gradient.success{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%)}.status.gradient.away,.status.gradient.warning{background:linear-gradient(120deg,#f6d365 0,#fda085 100%)}.status.gradient.busy,.status.gradient.danger{background:linear-gradient(120deg,#f3301a 0,#f37138 100%)}.card{position:relative;background-color:#fff;margin-bottom:30px;border:1px solid #e9eaec;border-radius:0;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.card-footer,.card-header{position:relative;min-height:55px;background-color:transparent}.card-header:first-child,.popover{border-radius:0}.card .bg-danger,.card .bg-gradient-danger,.card .bg-gradient-info,.card .bg-gradient-primary,.card .bg-gradient-success,.card .bg-gradient-warning,.card .bg-info,.card .bg-primary,.card .bg-success,.card .bg-warning,.card.bg-danger,.card.bg-gradient-danger,.card.bg-gradient-info,.card.bg-gradient-primary,.card.bg-gradient-success,.card.bg-gradient-warning,.card.bg-info,.card.bg-primary,.card.bg-success,.card.bg-warning{color:#f7f7f7}.card .bg-danger h1,.card .bg-danger h2,.card .bg-danger h3,.card .bg-danger h4,.card .bg-danger h5,.card .bg-danger h6,.card .bg-gradient-danger h1,.card .bg-gradient-danger h2,.card .bg-gradient-danger h3,.card .bg-gradient-danger h4,.card .bg-gradient-danger h5,.card .bg-gradient-danger h6,.card .bg-gradient-info h1,.card .bg-gradient-info h2,.card .bg-gradient-info h3,.card .bg-gradient-info h4,.card .bg-gradient-info h5,.card .bg-gradient-info h6,.card .bg-gradient-primary h1,.card .bg-gradient-primary h2,.card .bg-gradient-primary h3,.card .bg-gradient-primary h4,.card .bg-gradient-primary h5,.card .bg-gradient-primary h6,.card .bg-gradient-success h1,.card .bg-gradient-success h2,.card .bg-gradient-success h3,.card .bg-gradient-success h4,.card .bg-gradient-success h5,.card .bg-gradient-success h6,.card .bg-gradient-warning h1,.card .bg-gradient-warning h2,.card .bg-gradient-warning h3,.card .bg-gradient-warning h4,.card .bg-gradient-warning h5,.card .bg-gradient-warning h6,.card .bg-info h1,.card .bg-info h2,.card .bg-info h3,.card .bg-info h4,.card .bg-info h5,.card .bg-info h6,.card .bg-primary h1,.card .bg-primary h2,.card .bg-primary h3,.card .bg-primary h4,.card .bg-primary h5,.card .bg-primary h6,.card .bg-success h1,.card .bg-success h2,.card .bg-success h3,.card .bg-success h4,.card .bg-success h5,.card .bg-success h6,.card .bg-warning h1,.card .bg-warning h2,.card .bg-warning h3,.card .bg-warning h4,.card .bg-warning h5,.card .bg-warning h6,.card.bg-danger h1,.card.bg-danger h2,.card.bg-danger h3,.card.bg-danger h4,.card.bg-danger h5,.card.bg-danger h6,.card.bg-gradient-danger h1,.card.bg-gradient-danger h2,.card.bg-gradient-danger h3,.card.bg-gradient-danger h4,.card.bg-gradient-danger h5,.card.bg-gradient-danger h6,.card.bg-gradient-info h1,.card.bg-gradient-info h2,.card.bg-gradient-info h3,.card.bg-gradient-info h4,.card.bg-gradient-info h5,.card.bg-gradient-info h6,.card.bg-gradient-primary h1,.card.bg-gradient-primary h2,.card.bg-gradient-primary h3,.card.bg-gradient-primary h4,.card.bg-gradient-primary h5,.card.bg-gradient-primary h6,.card.bg-gradient-success h1,.card.bg-gradient-success h2,.card.bg-gradient-success h3,.card.bg-gradient-success h4,.card.bg-gradient-success h5,.card.bg-gradient-success h6,.card.bg-gradient-warning h1,.card.bg-gradient-warning h2,.card.bg-gradient-warning h3,.card.bg-gradient-warning h4,.card.bg-gradient-warning h5,.card.bg-gradient-warning h6,.card.bg-info h1,.card.bg-info h2,.card.bg-info h3,.card.bg-info h4,.card.bg-info h5,.card.bg-info h6,.card.bg-primary h1,.card.bg-primary h2,.card.bg-primary h3,.card.bg-primary h4,.card.bg-primary h5,.card.bg-primary h6,.card.bg-success h1,.card.bg-success h2,.card.bg-success h3,.card.bg-success h4,.card.bg-success h5,.card.bg-success h6,.card.bg-warning h1,.card.bg-warning h2,.card.bg-warning h3,.card.bg-warning h4,.card.bg-warning h5,.card.bg-warning h6{color:#fff}.card .bg-danger p,.card .bg-gradient-danger p,.card .bg-gradient-info p,.card .bg-gradient-primary p,.card .bg-gradient-success p,.card .bg-gradient-warning p,.card .bg-info p,.card .bg-primary p,.card .bg-success p,.card .bg-warning p,.card.bg-danger p,.card.bg-gradient-danger p,.card.bg-gradient-info p,.card.bg-gradient-primary p,.card.bg-gradient-success p,.card.bg-gradient-warning p,.card.bg-info p,.card.bg-primary p,.card.bg-success p,.card.bg-warning p{color:#f7f7f7}.card .bg-danger .card-header,.card .bg-gradient-danger .card-header,.card .bg-gradient-info .card-header,.card .bg-gradient-primary .card-header,.card .bg-gradient-success .card-header,.card .bg-gradient-warning .card-header,.card .bg-info .card-header,.card .bg-primary .card-header,.card .bg-success .card-header,.card .bg-warning .card-header,.card.bg-danger .card-header,.card.bg-gradient-danger .card-header,.card.bg-gradient-info .card-header,.card.bg-gradient-primary .card-header,.card.bg-gradient-success .card-header,.card.bg-gradient-warning .card-header,.card.bg-info .card-header,.card.bg-primary .card-header,.card.bg-success .card-header,.card.bg-warning .card-header{border-color:rgba(255,255,255,.3)!important}.card .bg-danger .card-footer,.card .bg-gradient-danger .card-footer,.card .bg-gradient-info .card-footer,.card .bg-gradient-primary .card-footer,.card .bg-gradient-success .card-footer,.card .bg-gradient-warning .card-footer,.card .bg-info .card-footer,.card .bg-primary .card-footer,.card .bg-success .card-footer,.card .bg-warning .card-footer,.card.bg-danger .card-footer,.card.bg-gradient-danger .card-footer,.card.bg-gradient-info .card-footer,.card.bg-gradient-primary .card-footer,.card.bg-gradient-success .card-footer,.card.bg-gradient-warning .card-footer,.card.bg-info .card-footer,.card.bg-primary .card-footer,.card.bg-success .card-footer,.card.bg-warning .card-footer{border-top:1px solid rgba(255,255,255,.2)}.card.card-shadow{-webkit-box-shadow:0 7px 20px 2px rgba(0,0,0,.2);-moz-box-shadow:0 7px 20px 2px rgba(0,0,0,.2);box-shadow:0 7px 20px 2px rgba(0,0,0,.2)}.card-header{padding:15px 25px;border-bottom:0}.card-header .card-title{margin-bottom:0;display:inline-block}.card-header p{padding-top:8px;margin-bottom:0}.card-body{padding:25px;position:relative}.card-footer{padding:10px 15px;border-top:1px solid #e9eaec}.card-footer .btn{margin-bottom:0}.card-toolbar{float:right}.card-toolbar ul{list-style:none;padding-left:0}.card-toolbar ul>li>.btn,.card-toolbar ul>li>a{margin-bottom:0;margin-right:10px;display:block}.card-toolbar ul>li>.btn{padding:7px 15px;font-size:13px}.bg-overlay>.card-toolbar{position:absolute;right:15px;top:10px}.card-title{color:#515365;margin-top:0;margin-bottom:15px}.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-refresh:before{position:absolute;top:0;left:0;width:100%;height:100%;z-index:4;background:#fff;background:rgba(255,255,255,.7)}.card-refresh:after{position:absolute;top:calc(50% - 20px);left:calc(50% - 20px);border:3px solid #e9eaec;border-top:3px solid #24d5d8;border-radius:50%;width:40px;height:40px;z-index:5;-webkit-animation:spin 1.2s linear infinite;-moz-animation:spin 1.2s linear infinite;-ms-animation:spin 1.2s linear infinite;-o-animation:spin 1.2s linear infinite;animation:spin 1.2s linear infinite;transform:translateX(-50%) translateY(-50%);-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-o-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%)}.draggable-item{cursor:move;cursor:grab;cursor:-moz-grab;cursor:-webkit-grab}@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-moz-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-ms-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-o-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}a.card{display:block}a.card:focus,a.card:hover{-webkit-box-shadow:0 7px 15px rgba(0,0,0,.075);-moz-box-shadow:0 7px 15px rgba(0,0,0,.075);box-shadow:0 7px 15px rgba(0,0,0,.075)}.bg-overlay{position:relative;overflow:hidden;color:#f2f2f2}.bg-overlay h1,.bg-overlay h2,.bg-overlay h3,.bg-overlay h4,.bg-overlay h5,.bg-overlay h6{color:#fff}.bg-overlay p{color:#f2f2f2}.bg-overlay:before{position:absolute;background:#0f0f17;opacity:.5;width:100%;height:100%;top:0;left:0;z-index:2}.bg-overlay>div{z-index:3}.bg-overlay .btn-default{color:#fff}.bg-overlay .btn-default:focus,.bg-overlay .btn-default:hover{color:#515365}.bg-overlay.primary:before{background:#6569df;opacity:.6}.bg-overlay.primary-gradient:before{background:linear-gradient(120deg,#b603c1 0,#7a38e0 100%);opacity:.8}.bg-overlay.success-gradient:before{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%);opacity:.8}.bg-overlay.info-gradient:before{background:linear-gradient(120deg,#6a4ee1 0,#05bdd7 100%);opacity:.7}.bg-overlay.warning-gradient:before{background:linear-gradient(120deg,#f6d365 0,#fda085 100%);opacity:.7}.bg-overlay.danger-gradient:before{background:linear-gradient(120deg,#f3301a 0,#f37138 100%);opacity:.7}.card-collapse-btn{transition:all .4s ease-in-out;-webkit-transition:all .4s ease-in-out;-moz-transition:all .4s ease-in-out;-o-transition:all .4s ease-in-out;-ms-transition:all .4s ease-in-out}.card-collapse-btn.active{transform:rotate(180deg);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg)}.page-title h1,.page-title h2,.page-title h3,.page-title h4,.page-title h5,.page-title h6,.page-title p,.page-title span{font-size:20px;margin-bottom:25px;margin-top:0}.dropdown.dropdown-animated:not(.scale-left) .dropdown-menu,.dropdown.dropdown-animated:not(.scale-right) .dropdown-menu{opacity:0;visibility:hidden;-webkit-transform:translateY(15px)!important;-moz-transform:translateY(15px)!important;-ms-transform:translateY(15px)!important;transform:translateY(15px)!important;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;display:block;margin:0;top:auto!important}.dropdown.dropdown-animated:not(.scale-left) .dropdown-menu.show,.dropdown.dropdown-animated:not(.scale-right) .dropdown-menu.show{opacity:1;visibility:visible;-webkit-transform:translateY(0)!important;-moz-transform:translateY(0)!important;-ms-transform:translateY(0)!important;transform:translateY(0)!important}.dropdown.dropdown-animated.scale-left .dropdown-menu{-webkit-transform-origin:top right!important;-moz-transform-origin:top right!important;-ms-transform-origin:top right!important;transform-origin:top right!important;transform:scale(0,0)!important;-webkit-transform:scale(0,0)!important;-moz-transform:scale(0,0)!important;-ms-transform:scale(0,0)!important;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;display:block;margin:0;right:0!important;left:auto!important;top:auto!important}.dropdown.dropdown-animated.scale-left .dropdown-menu.show{transform:scale(1,1)!important;-webkit-transform:scale(1,1)!important;-moz-transform:scale(1,1)!important;-ms-transform:scale(1,1)!important}.dropdown.dropdown-animated.scale-right .dropdown-menu{-webkit-transform-origin:top left;-moz-transform-origin:top left;-ms-transform-origin:top left;transform-origin:top left;transform:scale(0,0)!important;-webkit-transform:scale(0,0)!important;-moz-transform:scale(0,0)!important;-ms-transform:scale(0,0)!important;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;display:block;margin:0;top:auto!important}.dropdown.dropdown-animated.scale-right .dropdown-menu.show{transform:scale(1,1)!important;-webkit-transform:scale(1,1)!important;-moz-transform:scale(1,1)!important;-ms-transform:scale(1,1)!important}.dropdown-menu{border:0;border-radius:0;font-size:14px;min-width:180px;color:#8a8a8a;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.2);-moz-box-shadow:0 2px 5px rgba(0,0,0,.2);box-shadow:0 2px 5px rgba(0,0,0,.2);top:100%}.switch input[type=checkbox]+label:after,.switch input[type=checkbox]+label:before{top:0;left:0;content:"";position:absolute;display:block}.dropdown-menu.dropdown-md{min-width:250px}.dropdown-menu.dropdown-lg{min-width:360px}@media only screen and (max-width:767px){.dropdown-menu.dropdown-lg{min-width:280px}}.dropdown-menu.dropdown-xl{min-width:450px}.dropdown-menu>li.divider{border-bottom:1px solid #e9eaec;height:1px;overflow:hidden}.dropdown-menu>li>a{line-height:1.5;min-height:auto;padding:10px 15px;display:block;transition:all .2s ease-out;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;-ms-transition:all .2s ease-out;color:#8a8a8a}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#515365;text-decoration:none;background-color:#f7f7f8}.dropdown-menu.dropdown-grid{display:flex!important;flex-wrap:wrap;padding:10px}.dropdown-menu.dropdown-grid>li{display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;-webkit-box-pack:center;justify-content:center}.dropdown-menu.dropdown-grid>li>a{padding:10px;border:1px solid #e9eaec;margin:7px;border-radius:4px}.dropdown-menu.dropdown-grid.col-2>li{flex-basis:50%}.dropdown-menu.dropdown-grid.col-3>li{flex-basis:33.333333%}@media only screen and (max-width:767px){.dropdown-menu.dropdown-xl{min-width:280px}.dropdown-menu.dropdown-grid.col-3>li{flex-basis:50%}}.dropdown-menu.dropdown-grid.col-4>li{flex-basis:25%}@media only screen and (max-width:767px){.dropdown-menu.dropdown-grid.col-4>li{flex-basis:50%}}.dropdown-item{line-height:1.5;min-height:auto;padding:10px 20px;display:block;transition:all .15s ease-out;-webkit-transition:all .15s ease-out;-moz-transition:all .15s ease-out;-o-transition:all .15s ease-out;-ms-transition:all .15s ease-out;color:#8a8a8a}.dropdown-item:focus,.dropdown-item:hover{color:#515365;text-decoration:none;background-color:#f7f7f8}.dropdown-item.disabled{opacity:.3;cursor:not-allowed}.dropdown-item.disabled:focus,.dropdown-item.disabled:hover{background-color:transparent}.dropdown-item.active{background-color:#f7f7f8;color:#515365}.dropdown-toggle:after{text-align:center;display:inline;border:0;font-family:Material Design Icons;content:"\F140";line-height:0;vertical-align:middle;position:relative}.dropdown-header{padding:10px 20px;font-weight:500;color:#717171;font-size:15px}.dropdown,.dropup{display:inline-block}.accordion>.card{margin-bottom:15px}.accordion>.card>.card-header{padding:0}.accordion>.card>.card-header>.card-title>a{padding:15px 25px;display:block;color:#515365}.accordion>.card>.card-header>.card-title>a:not(.collapsed):after{transform:rotate(90deg);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-o-transform:rotate(90deg);-ms-transform:rotate(90deg)}.accordion>.card>.card-header>.card-title>a:after{content:"\F142";font-family:"Material Design Icons";float:left;margin-right:10px;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.accordion>.card .card-body{padding-top:5px}.accordion.nested>.card{margin-bottom:0;border-bottom:0}.accordion.nested>.card:last-child{border-bottom:1px solid #e9eaec}.accordion.borderless>.card{margin-bottom:0;border-top:0;border-left:0;border-right:0}.accordion.borderless>.card:last-child{border-bottom:0}.popover{border:1px solid #e9eaec;-webkit-box-shadow:0 9px 12px rgba(0,0,0,.075);-moz-box-shadow:0 9px 12px rgba(0,0,0,.075);box-shadow:0 9px 12px rgba(0,0,0,.075)}.form-control,.page-link:focus{box-shadow:none}.popover-header{background-color:#fafafa;color:#515365;border-bottom:1px solid #e9eaec;border-top-left-radius:0;border-top-right-radius:0}.popover-body{padding:10px 15px;color:#515365}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{border-right-color:#e9eaec}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{border-top-color:#e9eaec}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{border-left-color:#e9eaec}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{border-bottom-color:#e9eaec}.tooltip-inner{background-color:#212224;border-radius:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{border-top-color:#212224}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{border-right-color:#212224}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{border-bottom-color:#212224}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{border-left-color:#212224}.page-link{border:1px solid transparent;border-radius:5px;padding:.4rem .7rem;margin:0 2.5px;color:#8a8a8a;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.input-group-text .checkbox input[type=checkbox]+label:before,.input-group-text .radio input[type=radio]+label:before{margin-right:0}.page-link:hover{color:#24d5d8;text-decoration:none;background-color:transparent;border-color:transparent}.page-item.disabled .page-link{color:#cacaca;border-color:transparent}.page-item.active .page-link{background:linear-gradient(120deg,#1dccdf 0,#1de4bd 100%);border-color:transparent}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{line-height:1.8;border-color:#e9eaec}.table-sm>tbody>tr>td,.table-sm>tbody>tr>th,.table-sm>tfoot>tr>td,.table-sm>tfoot>tr>th,.table-sm>thead>tr>td,.table-sm>thead>tr>th{padding:7.5px}.table-lg>tbody>tr>td,.table-lg>tbody>tr>th,.table-lg>tfoot>tr>td,.table-lg>tfoot>tr>th,.table-lg>thead>tr>td,.table-lg>thead>tr>th{padding:15px}.table-xl>tbody>tr>td,.table-xl>tbody>tr>th,.table-xl>tfoot>tr>td,.table-xl>tfoot>tr>th,.table-xl>thead>tr>td,.table-xl>thead>tr>th{padding:20px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#fbfbfb}.table-hover>tbody>tr:hover{background-color:#fafafa}.table-bordered{border:1px solid #e9eaec}.table>thead>tr>th{color:#717171;border-bottom:1px solid #e9eaec}.table .thead-dark th{background-color:#515365;border-color:#515365}.table .thead-light th,.table tr.selected{background-color:#fafafa}.table .thead-light th{border-color:#e9eaec;color:#717171}.table td,.table th{vertical-align:middle}.form-control:disabled,.form-control[readonly],.input-group-text{background-color:#f4f4f5}@media only screen and (max-width:992px){.table-overflow{width:100%;overflow-x:auto}}.form-group{margin-bottom:25px}.form-group label.control-label{display:inline-block;margin-bottom:.5rem;font-size:13px;font-weight:500;text-transform:uppercase}.checkbox input[type=checkbox]+label:before,.radio input[type=radio]+label:before{width:22px;height:22px;font-family:'Material Design Icons';font-weight:400;vertical-align:bottom;text-align:center}.form-group label.col-form-label{margin-bottom:0;line-height:1.5;padding-top:calc(.75rem + 1px);padding-bottom:calc(.75rem + 1px)}.form-control{border:1px solid #e4e5e7;border-radius:5px;line-height:2.2;font-size:14px;color:#8a8a8a;transition:all .2s ease-in;-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;-o-transition:all .2s ease-in;-ms-transition:all .2s ease-in}.form-control::-webkit-input-placeholder{color:#bdbdbd}.form-control:-moz-placeholder{color:#bdbdbd}.form-control::-moz-placeholder{color:#bdbdbd}.form-control:-ms-input-placeholder{color:#bdbdbd}.form-control:focus{outline:0;-webkit-box-shadow:1px 1px 15px rgba(0,0,0,.075);-moz-box-shadow:1px 1px 15px rgba(0,0,0,.075);box-shadow:1px 1px 15px rgba(0,0,0,.075);border-color:#24d5d8}.form-control.error{border-color:#fd3259}.form-control:disabled:focus,.form-control[readonly]:focus{border-color:#e9eaec}.form-control:disabled{cursor:not-allowed}.form-control-plaintext{padding-top:.375rem;padding-bottom:.375rem;line-height:2.2}.form-text{margin-top:5px;color:#979797}.form-control-sm,.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:.15rem .75rem}.form-control-lg,.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:.7rem .75rem}.icon-input{position:relative}.icon-input>.form-control{padding-left:50px;padding-right:50px}.icon-input>i{position:absolute;top:0;left:15px;font-size:20px;padding-top:10px;line-height:1;color:#bdbdbd}.input-group-text .checkbox,.input-group-text .radio{padding:0}.input-group>.input-group-append>.btn,.input-group>.input-group-prepend>.btn{margin:0}.input-group>.input-group-append.dropdown,.input-group>.input-group-prepend.dropdown{display:flex}.input-group-text{border:1px solid #e4e5e7;color:#a4a4a4}.textarea-md{min-height:150px}.textarea-lg{min-height:250px}.checkbox,.radio{min-height:auto;position:relative}.checkbox{padding:10px 0}.checkbox input[type=checkbox]{margin:0;display:none;width:22px}.checkbox input[type=checkbox]+label{padding-left:0}.checkbox input[type=checkbox]+label:before{content:"\F12C";display:inline-block;margin-right:10px;border:2px solid #e9eaec;border-radius:3px;font-size:15px;line-height:19px;background:#fff;color:transparent;cursor:pointer;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.checkbox input[type=checkbox]:checked+label:before{background:#24d5d8;border-color:#24d5d8;color:#fff}.checkbox input[type=checkbox].disabled+label:before,.checkbox input[type=checkbox]:disabled+label:before{cursor:not-allowed}.checkbox input[type=checkbox].error+label:before{border-color:#ffd0d9}.checkbox.to-do input[type=checkbox]:checked+label{text-decoration:line-through}.checkbox.checkbox-primary input[type=checkbox]:checked+label:before{background:#6569df;border-color:#6569df;color:#fff}.checkbox.checkbox-info input[type=checkbox]:checked+label:before{background:#04a1f4;border-color:#04a1f4;color:#fff}.checkbox.checkbox-warning input[type=checkbox]:checked+label:before{background:#fecd2f;border-color:#fecd2f;color:#fff}.checkbox.checkbox-danger input[type=checkbox]:checked+label:before{background:#fd3259;border-color:#fd3259;color:#fff}.radio{padding:10px 0}.radio input[type=radio]{margin:0;display:none;width:22px}.radio input[type=radio]+label{padding-left:0}.radio input[type=radio]+label:before{content:"\F12F";display:inline-block;margin-right:10px;border:2px solid #e9eaec;border-radius:50%;font-size:11px;line-height:18px;background-color:#fff;color:transparent;cursor:pointer;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.radio input[type=radio]:checked+label:before{color:#24d5d8;border-color:#24d5d8}.radio input[type=radio].disabled+label:before,.radio input[type=radio]:disabled+label:before{cursor:not-allowed}.radio.radio-primary input[type=radio]:checked+label:before{color:#6569df;border-color:#6569df}.radio.radio-info input[type=radio]:checked+label:before{color:#04a1f4;border-color:#04a1f4}.radio.radio-warning input[type=radio]:checked+label:before{color:#fecd2f;border-color:#fecd2f}.radio.radio-danger input[type=radio]:checked+label:before{color:#fd3259;border-color:#fd3259}.checkbox label,.radio label{cursor:pointer}.switch input[type=checkbox]{opacity:0;position:absolute}.switch input[type=checkbox]+label{position:relative;display:inline-block;transition:.4s ease;-webkit-transition:.4s ease;-moz-transition:.4s ease;-o-transition:.4s ease;-ms-transition:.4s ease;height:20px;width:35px;border:1px solid #e9eaec;border-radius:60px;cursor:pointer}.switch input[type=checkbox]+label:before{transition:.2s cubic-bezier(.24,0,.5,1);-webkit-transition:.2s cubic-bezier(.24,0,.5,1);-moz-transition:.2s cubic-bezier(.24,0,.5,1);-o-transition:.2s cubic-bezier(.24,0,.5,1);-ms-transition:.2s cubic-bezier(.24,0,.5,1);height:20px;width:35px;border-radius:30px}.switch input[type=checkbox]+label:after{box-shadow:0 0 0 1px rgba(0,0,0,.1),0 4px 0 0 rgba(0,0,0,.04),0 4px 9px rgba(0,0,0,.13),0 3px 3px rgba(0,0,0,.05);transition:.35s cubic-bezier(.54,1.6,.5,1);-webkit-transition:.35s cubic-bezier(.54,1.6,.5,1);-moz-transition:.35s cubic-bezier(.54,1.6,.5,1);-o-transition:.35s cubic-bezier(.54,1.6,.5,1);-ms-transition:.35s cubic-bezier(.54,1.6,.5,1);background:#f7f7f7;height:19px;width:19px;border-radius:60px}.switch input[type=checkbox]:checked+label:before{background:#24d5d8;transition:width .2s cubic-bezier(0,0,0,.1);-webkit-transition:width .2s cubic-bezier(0,0,0,.1);-moz-transition:width .2s cubic-bezier(0,0,0,.1);-o-transition:width .2s cubic-bezier(0,0,0,.1);-ms-transition:width .2s cubic-bezier(0,0,0,.1)}.switch input[type=checkbox]:checked+label:after{left:16px}.switch input[type=checkbox]:disabled+label{opacity:.7;cursor:not-allowed}.switch.switch-primary input[type=checkbox]:checked+label:before{background:#6569df}.switch.switch-info input[type=checkbox]:checked+label:before{background:#04a1f4}.switch.switch-warning input[type=checkbox]:checked+label:before{background:#fecd2f}.switch.switch-danger input[type=checkbox]:checked+label:before{background:#fd3259}.test-wrapper{padding:0;margin:0;overflow:auto;min-height:100%;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out;border:1px solid #e9eaec}@media only screen and (max-width:992px){.test-wrapper{position:absolute;left:0;width:100%}}.test-wrapper .test-list{position:relative;padding:0;width:100%;overflow-y:hidden;background-color:#fff}@media only screen and (min-width:992px){.test-wrapper .test-list{width:25%;border-right:1px solid #e9eaec;float:left}.test-wrapper .test-list .test-list-wrapper{height:calc(100vh - 65px - 115px - 41px)}}@media only screen and (min-width:992px) and (max-width:1440px){.test-wrapper .test-list{width:35%}}.test-wrapper .test-list .test-list-tools{padding:5px 15px;border-bottom:1px solid #e9eaec;text-align:right;display:block}.test-wrapper .test-list .test-list-tools .tools{list-style:none;padding:0}.test-wrapper .test-list .test-list-tools .tools>li{display:inline-block;padding:3px 5px}.test-wrapper .test-list .test-list-tools .tools>li>a{font-size:16px;color:#8a8a8a;display:block;transition:all .2s ease-in-out;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out}.test-wrapper .test-list .test-list-tools .tools>li>a:focus,.test-wrapper .test-list .test-list-tools .tools>li>a:hover{color:#24d5d8}.test-wrapper .test-list .test-list-wrapper{position:relative;overflow-y:auto}.test-wrapper .test-list .test-list-wrapper .test-list-item{padding-left:0;list-style:none}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item{position:relative;display:table;width:100%;padding:15px;border-bottom:1px solid #e9eaec;cursor:pointer;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item:focus,.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item:hover{background-color:#fafafa}@media only screen and (min-width:992px){.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item.active{background-color:#fafafa}}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item a{color:#8a8a8a}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-avatar{position:absolute;top:20px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-avatar img{width:30px;height:30px;border-radius:50px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail{vertical-align:top;display:table-cell;width:100%;padding-left:45px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail p{margin-bottom:0}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail .name{font-size:16px;color:#515365}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail .subject{color:#515365;font-weight:500;margin-bottom:5px}.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item .test-detail .datetime{position:absolute;top:20px;right:15px;font-size:11px}.test-wrapper .test-content{float:left;width:75%;position:relative;padding:0;background-color:#fff;height:calc(100vh - 65px - 115px);overflow:auto;transition:all .3s ease-in-out;-webkit-transition:all .3s ease-in-out;-moz-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;-ms-transition:all .3s ease-in-out}.test-wrapper .test-content.no-inbox-view{width:100%}@media only screen and (min-width:992px) and (max-width:1440px){.test-wrapper .test-content{width:65%}}@media only screen and (max-width:992px){.test-wrapper .test-content{position:fixed;width:100%;height:calc(100vh - 65px);top:calc(65px + 20px);left:-100%}.test-wrapper .test-content.open{left:0}}.test-wrapper .test-content .test-content-tools{padding:10px 15px;border-bottom:1px solid #e9eaec}@media only screen and (min-width:992px){.test-wrapper .test-content .test-content-tools{display:none}}.test-wrapper .test-content .test-content-tools ul{list-style:none;padding:0;display:inline-block}.test-wrapper .test-content .test-content-tools ul li{display:inline-block}.test-wrapper .test-content .test-content-tools ul li a{font-size:16px;padding:0 10px;color:#8a8a8a}.test-wrapper .test-content .test-content-tools ul li a:focus,.test-wrapper .test-content .test-content-tools ul li a:hover{color:#24d5d8}.test-wrapper .test-content .test-content-detail{position:relative;padding:30px;max-height:calc(100vh - 65px)}@media only screen and (max-width:992px){.test-wrapper .test-content .test-content-detail{padding:15px}.mail-nav-active .sec-side-nav{left:0}}.test-wrapper .test-content .test-content-detail .detail-head{position:relative}.test-wrapper .test-content .test-content-detail .detail-head .thumb-img{width:50px;height:50px}.test-wrapper .test-content .test-content-detail .detail-head .info{height:50px;padding-left:65px}.test-wrapper .test-content .test-content-detail .detail-head .info .title{padding-top:5px}.test-wrapper .test-content .test-content-detail .detail-head .info .sub-title{max-width:100%}.test-wrapper .test-content .test-content-detail .detail-head .tools{padding:0;list-style:none;float:right;margin-top:15px}.test-wrapper .test-content .test-content-detail .detail-head .tools>li{display:inline-block;padding:10px}.test-wrapper .test-content .test-content-detail .detail-head .tools>li a{color:#8a8a8a}.test-wrapper .test-content .test-content-detail .detail-head .tools>li a:focus,.test-wrapper .test-content .test-content-detail .detail-head .tools>li a:hover{color:#515365}.test-wrapper .test-content .test-content-detail .detail-body{padding:25px 30px;position:relative}.test-wrapper .test-content .test-content-detail .detail-foot{padding:15px 30px}.test-wrapper .test-content .test-content-detail .detail-foot .attachments{list-style:none;padding-left:0}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li{display:inline-block;border:1px solid #e9eaec;margin-right:10px;margin-bottom:10px;border-radius:6px}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a{display:block;color:#8a8a8a}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-icon{float:left;padding:8px 15px;font-size:28px;border-right:1px solid #e9eaec}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-info{display:inline-block;padding:8px 15px 8px 10px}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-info .file-name,.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a .file-info .file-size{display:block}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:focus,.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:hover{color:#515365}.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:focus .file-icon,.test-wrapper .test-content .test-content-detail .detail-foot .attachments>li>a:hover .file-icon{color:#24d5d8}.test-wrapper .email-compose{position:relative}.test-wrapper .email-compose .email-compose-tools{background-color:#fafafa;padding:10px 15px;border-bottom:1px solid #e9eaec}@media only screen and (min-width:992px){.test-wrapper .email-compose .email-compose-tools{display:none}}.test-wrapper .email-compose .email-compose-tools ul{list-style:none;padding:0;display:inline-block}.test-wrapper .email-compose .email-compose-tools ul li{display:inline-block}.test-wrapper .email-compose .email-compose-tools ul li a{font-size:16px;padding:0 10px;color:#8a8a8a}.test-wrapper .email-compose .email-compose-tools ul li a:focus,.test-wrapper .email-compose .email-compose-tools ul li a:hover{color:#24d5d8}.test-wrapper .email-compose .email-compose-body{padding:30px 20px}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input{box-shadow:none;border:0;border-bottom:1px solid #e9eaec;font-size:14px;padding:12px}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input::-webkit-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input:-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input::-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .selectize-input input:-ms-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject{border:0;padding:12px}.test-wrapper .email-compose .email-compose-body .send-header .subject::-webkit-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject:-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject::-moz-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .send-header .subject:-ms-input-placeholder{font-size:14px;color:#bdbdbd}.test-wrapper .email-compose .email-compose-body .note-editor{margin-top:5px}.test-wrapper .email-compose .email-compose-body .note-editor.note-frame .note-statusbar{display:none}.test-wrapper .email-compose .email-compose-body .note-editor .panel-heading.note-toolbar{position:absolute;z-index:9;width:100%;bottom:0;border-bottom:0;border-top:1px solid #e9eaec}@media only screen and (max-width:992px){.mail-nav-active .test-wrapper{left:200px}} - /** * Featherlight - ultra slim jQuery lightbox * Version 1.5.0 - http://noelboss.github.io/featherlight/ @@ -53,9 +44,6 @@ body,p{color:#8a8a8a;font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFo **/ @media all{.featherlight{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:2147483647;text-align:center;white-space:nowrap;cursor:pointer;background:#333;background:rgba(0,0,0,0)}.featherlight:last-of-type{background:rgba(0,0,0,.8)}.featherlight:before{content:'';display:inline-block;height:100%;vertical-align:middle;margin-right:-.25em}.featherlight .featherlight-content{position:relative;text-align:left;vertical-align:middle;display:inline-block;overflow:auto;padding:25px 25px 0;border-bottom:25px solid transparent;margin-left:5%;margin-right:5%;max-height:95%;background:#fff;cursor:auto;white-space:normal}.featherlight .featherlight-inner{display:block}.featherlight .featherlight-close-icon{position:absolute;z-index:9999;top:0;right:0;line-height:25px;width:25px;cursor:pointer;text-align:center;font-family:Arial,sans-serif;background:#fff;background:rgba(255,255,255,.3);color:#000}.featherlight .featherlight-image{width:100%}.featherlight-iframe .featherlight-content{border-bottom:0;padding:0}.featherlight iframe{border:0}.featherlight *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}}@media only screen and (max-width:1024px){.featherlight .featherlight-content{margin-left:10px;margin-right:10px;max-height:98%;padding:10px 10px 0;border-bottom:10px solid transparent}} - - - /** * json-tree * Copyright (c) 2013 Leonardo Menezes @@ -89,11 +77,29 @@ td { word-break: break-all; } +/** + * Topnav + * +**/ +.header, .header .header-container .nav-left>li>a, .header .header-container .nav-right>li>a { + height: 55px; + min-height: 55px; + line-height: 55px; +} +.header .header-container .nav-logo>a .logo { + min-height: 52px; +} +.header .header-container .nav-left>li>a i { + font-size: 18px; +} /** * Sidenav * **/ +.side-nav { + top: 55px; +} .side-nav-controls { position: absolute; left: -15px; @@ -109,7 +115,7 @@ td { * **/ .page-container .main-content { - padding: 62px 0 0; + padding: 55px 0 0; min-height: calc(100vh); } .test-wrapper { diff --git a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl index 0994f0b..ab9019b 100644 --- a/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl +++ b/src/main/resources/com/aventstack/extentreports/view/spark/partials/head.ftl @@ -1,4 +1,4 @@ -<#assign resourceCDN=config.getConfig('resourceCDN') cdnURI="cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@" csscommit="ff53917fbbdb5ef820abbbe4d199a6942dc771ff" jscommit="832f979664f9d68bf618db3ac87498ac6c1a6390" iconcommit="ff53917fbbdb5ef820abbbe4d199a6942dc771ff"> +<#assign resourceCDN=config.getConfig('resourceCDN') cdnURI="cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@" csscommit="a7f1745dfbc791b1f7f87e71185e80a0ad216a69" jscommit="d81f3e214d4e48889dade2a5c50a89be6c588423" iconcommit="d81f3e214d4e48889dade2a5c50a89be6c588423"> <#if resourceCDN=="extentreports"> <#assign cdnURI="extentreports.com/resx" csscommit="" jscommit="" iconcommit=""> From 4537cb63f74ea45dccddccc7992c714d2a3c88f8 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sat, 4 Jan 2020 23:17:34 -0800 Subject: [PATCH 56/77] ExtentReports implements createDomainFromJsonArchive instead of standalone call --- .../extentreports/ExtentReports.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/aventstack/extentreports/ExtentReports.java b/src/main/java/com/aventstack/extentreports/ExtentReports.java index 1a3197d..1e62755 100644 --- a/src/main/java/com/aventstack/extentreports/ExtentReports.java +++ b/src/main/java/com/aventstack/extentreports/ExtentReports.java @@ -1,9 +1,12 @@ package com.aventstack.extentreports; +import java.io.File; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.List; +import com.aventstack.extentreports.convert.TestModelReportBuilder; import com.aventstack.extentreports.gherkin.GherkinDialectProvider; import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel; import com.aventstack.extentreports.model.Media; @@ -357,7 +360,7 @@ public void setTestRunnerOutput(String log) { * * @return {@link ExtentKlovReporter} */ - public ExtentReports tryResolveScreenCapturePath() { + public ExtentReports tryResolveMediaPath() { setImagePathResolveDir(IMAGE_PATH_RESOLVER_DIR); return this; } @@ -376,6 +379,33 @@ public ExtentReports tryResolveScreenCapturePath(String[] paths) { return this; } + /** + * Creates the internal models by consuming a JSON archive from a previous run + * session. This provides the same functionality as available in earlier versions + * via appendExisting, with the exception of being accessible by + * all reporters instead of just one. + * + * @param jsonFile The JSON archive file + * @throws IOException Exception thrown if the jsonFile is not found + */ + public void createDomainFromJsonArchive(File jsonFile) throws IOException { + TestModelReportBuilder modelBuilder = new TestModelReportBuilder(); + modelBuilder.createDomainFromJsonArchive(this, jsonFile); + } + + /** + * Creates the internal models by consuming a JSON archive from a previous run + * session. This provides the same functionality as available in earlier versions + * via appendExisting, with the exception of being accessible by + * all reporters instead of just one. + * + * @param jsonFile The JSON archive file + * @throws jsonFilePath Exception thrown if the jsonFilePath is not found + */ + public void createDomainFromJsonArchive(String jsonFilePath) throws IOException { + createDomainFromJsonArchive(new File(jsonFilePath)); + } + /** * Use this setting when building post-execution reports, such as from TestNG * IReporter. This setting allows setting test with your own time-stamps. With From bfa32eb94554f87fd9e4232522e4209ea7957807 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sun, 5 Jan 2020 14:06:24 -0800 Subject: [PATCH 57/77] add all pro reporters (for compatibility) --- .../reporter/ExtentAventReporter.java | 33 ++++++++++++++++ .../reporter/ExtentBDDReporter.java | 33 ++++++++++++++++ .../reporter/ExtentCardsReporter.java | 33 ++++++++++++++++ .../reporter/ExtentEmailReporter.java | 38 +++++++++++++++++++ .../reporter/ExtentTabularReporter.java | 33 ++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java create mode 100644 src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java new file mode 100644 index 0000000..cfa4b39 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentAventReporter.java @@ -0,0 +1,33 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; + +import com.aventstack.extentreports.ReportAggregates; + +/** + * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options + * via the config() method. + */ +public class ExtentAventReporter + extends BasicFileReporter { + + private static final String REPORTER_NAME = "avent"; + + public ExtentAventReporter(String path) { + super(path); + } + + public ExtentAventReporter(File file) { + super(file); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java new file mode 100644 index 0000000..0a609b7 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentBDDReporter.java @@ -0,0 +1,33 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; + +import com.aventstack.extentreports.ReportAggregates; + +/** + * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options + * via the config() method. + */ +public class ExtentBDDReporter + extends BasicFileReporter { + + private static final String REPORTER_NAME = "bdd"; + + public ExtentBDDReporter(String path) { + super(path); + } + + public ExtentBDDReporter(File file) { + super(file); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java new file mode 100644 index 0000000..a3dbee1 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentCardsReporter.java @@ -0,0 +1,33 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; + +import com.aventstack.extentreports.ReportAggregates; + +/** + * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options + * via the config() method. + */ +public class ExtentCardsReporter + extends BasicFileReporter { + + private static final String REPORTER_NAME = "cards"; + + public ExtentCardsReporter(String path) { + super(path); + } + + public ExtentCardsReporter(File file) { + super(file); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java new file mode 100644 index 0000000..c785a06 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentEmailReporter.java @@ -0,0 +1,38 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; + +import com.aventstack.extentreports.ReportAggregates; +import com.aventstack.extentreports.SourceProvider; + +/** + * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several + * configuration options via the config() method. + */ +public class ExtentEmailReporter extends BasicFileReporter implements SourceProvider { + + private static final String REPORTER_NAME = "email"; + + public ExtentEmailReporter(String path) { + super(path); + } + + public ExtentEmailReporter(File file) { + super(file); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + + @Override + public String getSource() { + return super.getSource(); + } + +} diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java new file mode 100644 index 0000000..ac73203 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentTabularReporter.java @@ -0,0 +1,33 @@ +package com.aventstack.extentreports.reporter; + +import java.io.File; + +import com.aventstack.extentreports.ReportAggregates; + +/** + * The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options + * via the config() method. + */ +public class ExtentTabularReporter + extends BasicFileReporter { + + private static final String REPORTER_NAME = "tabular"; + + public ExtentTabularReporter(String path) { + super(path); + } + + public ExtentTabularReporter(File file) { + super(file); + } + + @Override + public synchronized void flush(ReportAggregates reportAggregates) { + } + + @Override + public String getReporterName() { + return REPORTER_NAME; + } + +} From 344952c6f4178d6cbe2a377524cacdf32c848ee2 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sun, 5 Jan 2020 14:06:33 -0800 Subject: [PATCH 58/77] Create SourceProvider.java --- .../com/aventstack/extentreports/SourceProvider.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/com/aventstack/extentreports/SourceProvider.java diff --git a/src/main/java/com/aventstack/extentreports/SourceProvider.java b/src/main/java/com/aventstack/extentreports/SourceProvider.java new file mode 100644 index 0000000..eccc815 --- /dev/null +++ b/src/main/java/com/aventstack/extentreports/SourceProvider.java @@ -0,0 +1,12 @@ +package com.aventstack.extentreports; + +/** + * Some formatters can provide the source which is also written to file, + * for example, Email formatters or reporters. Along with writing the contents + * to a file, you can retrieve the source using which an email can be sent. + */ +public interface SourceProvider { + + String getSource(); + +} From 478c2ee6578ee28d84fc4b9f47ffbc8236734f14 Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sun, 5 Jan 2020 14:07:04 -0800 Subject: [PATCH 59/77] base64 fix, includes base64 prefix --- .../com/aventstack/extentreports/model/ScreenCapture.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java index 1562552..2f4b988 100644 --- a/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java +++ b/src/main/java/com/aventstack/extentreports/model/ScreenCapture.java @@ -10,6 +10,7 @@ public String getBase64String() { } public void setBase64String(String base64) { + base64 = base64.contains("data:") || base64.contains("image/") ? base64 : "data:image/png;base64," + base64; this.base64 = base64; } @@ -23,8 +24,10 @@ public Boolean isBase64() { public String getSource() { if (getBase64String() != null) - return "base64-img"; - return ""; + return "base64-img"; + String path = "file:///"; + path += getScreenCapturePath().replace("\\","/"); + return ""; } } From f39998964b117ca30ad65abe93b11f0bec946afe Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sun, 5 Jan 2020 16:15:17 -0800 Subject: [PATCH 60/77] ExtentSparkReporter uses SPA as default view --- .../aventstack/extentreports/reporter/ExtentSparkReporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java b/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java index 0070379..5ff5f7f 100644 --- a/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java +++ b/src/main/java/com/aventstack/extentreports/reporter/ExtentSparkReporter.java @@ -29,7 +29,7 @@ public class ExtentSparkReporter extends BasicFileReporter { "src/main/resources/spark.properties" }; private ExtentSparkReporterConfiguration externalUserConfiguration = new ExtentSparkReporterConfiguration(this); - private ViewStyle viewStyle; + private ViewStyle viewStyle = ViewStyle.SPA; public ExtentSparkReporter(String path) { super(path); From 27c759aa40b3659f230dc72588d10647f363fb1a Mon Sep 17 00:00:00 2001 From: anshooarora Date: Sun, 5 Jan 2020 16:15:37 -0800 Subject: [PATCH 61/77] minor style improvements for dark theme --- .../offline/spark/css/spark-style.css | 26 +++++++++++-------- .../offline/spark/js/spark-script.js | 19 -------------- .../view/spark/macros/recurse_nodes.ftl | 4 +-- .../view/spark/partials/bdd-content.ftl | 6 ++--- 4 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css index 23b9f2c..997d18b 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/css/spark-style.css @@ -22,9 +22,6 @@ */ @-webkit-keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);animation-timing-function:cubic-bezier(.215,.61,.355,1);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);animation-timing-function:cubic-bezier(.215,.61,.355,1);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);animation-timing-function:cubic-bezier(.755,.05,.855,.06);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;-webkit-transform-origin:center bottom;animation-name:bounce;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.headShake{-webkit-animation-name:headShake;-webkit-animation-timing-function:ease-in-out;animation-name:headShake;animation-timing-function:ease-in-out}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-animation-name:swing;-webkit-transform-origin:top center;animation-name:swing;transform-origin:top center}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;-webkit-transform-origin:center;animation-name:jello;transform-origin:center}@-webkit-keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}.heartBeat{-webkit-animation-duration:1.3s;-webkit-animation-name:heartBeat;-webkit-animation-timing-function:ease-in-out;animation-duration:1.3s;animation-name:heartBeat;animation-timing-function:ease-in-out}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{-webkit-transform:scale3d(1.03,1.03,1.03);opacity:1;transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{-webkit-transform:scaleX(1);opacity:1;transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{-webkit-transform:scale3d(1.03,1.03,1.03);opacity:1;transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{-webkit-transform:scaleX(1);opacity:1;transform:scaleX(1)}}.bounceIn{-webkit-animation-duration:.75s;-webkit-animation-name:bounceIn;animation-duration:.75s;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,-3000px,0);opacity:0;transform:translate3d(0,-3000px,0)}60%{-webkit-transform:translate3d(0,25px,0);opacity:1;transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,-3000px,0);opacity:0;transform:translate3d(0,-3000px,0)}60%{-webkit-transform:translate3d(0,25px,0);opacity:1;transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(-3000px,0,0);opacity:0;transform:translate3d(-3000px,0,0)}60%{-webkit-transform:translate3d(25px,0,0);opacity:1;transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(-3000px,0,0);opacity:0;transform:translate3d(-3000px,0,0)}60%{-webkit-transform:translate3d(25px,0,0);opacity:1;transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(3000px,0,0);opacity:0;transform:translate3d(3000px,0,0)}60%{-webkit-transform:translate3d(-25px,0,0);opacity:1;transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(3000px,0,0);opacity:0;transform:translate3d(3000px,0,0)}60%{-webkit-transform:translate3d(-25px,0,0);opacity:1;transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,3000px,0);opacity:0;transform:translate3d(0,3000px,0)}60%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:translate3d(0,3000px,0);opacity:0;transform:translate3d(0,3000px,0)}60%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{-webkit-transform:scale3d(1.1,1.1,1.1);opacity:1;transform:scale3d(1.1,1.1,1.1)}to{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{-webkit-transform:scale3d(1.1,1.1,1.1);opacity:1;transform:scale3d(1.1,1.1,1.1)}to{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-duration:.75s;-webkit-animation-name:bounceOut;animation-duration:.75s;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{-webkit-transform:translate3d(0,-20px,0);opacity:1;transform:translate3d(0,-20px,0)}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{-webkit-transform:translate3d(20px,0,0);opacity:1;transform:translate3d(20px,0,0)}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{-webkit-transform:translate3d(20px,0,0);opacity:1;transform:translate3d(20px,0,0)}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{-webkit-transform:translate3d(-20px,0,0);opacity:1;transform:translate3d(-20px,0,0)}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{-webkit-transform:translate3d(-20px,0,0);opacity:1;transform:translate3d(-20px,0,0)}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{-webkit-transform:translate3d(0,20px,0);opacity:1;transform:translate3d(0,20px,0)}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{-webkit-transform:translate3d(0,20px,0);opacity:1;transform:translate3d(0,20px,0)}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInDown{0%{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInDownBig{0%{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInLeft{0%{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInLeftBig{0%{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInRight{0%{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInRightBig{0%{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInUp{0%{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes fadeInUpBig{0%{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{-webkit-transform:translate3d(0,100%,0);opacity:0;transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{-webkit-transform:translate3d(0,2000px,0);opacity:0;transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{-webkit-transform:translate3d(-100%,0,0);opacity:0;transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{-webkit-transform:translate3d(-2000px,0,0);opacity:0;transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0);opacity:0;transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{-webkit-transform:translate3d(2000px,0,0);opacity:0;transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{-webkit-transform:translate3d(0,-100%,0);opacity:0;transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{-webkit-transform:translate3d(0,-2000px,0);opacity:0;transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn)}40%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg)}50%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg)}80%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg)}to{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg)}}@keyframes flip{0%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn)}40%{-webkit-animation-timing-function:ease-out;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);animation-timing-function:ease-out;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg)}50%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg)}80%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg)}to{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);animation-timing-function:ease-in;transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg)}}.animated.flip{-webkit-animation-name:flip;-webkit-backface-visibility:visible;animation-name:flip;backface-visibility:visible}@-webkit-keyframes flipInX{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateX(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);opacity:1;transform:perspective(400px) rotateX(10deg)}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateX(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateX(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateX(-20deg)}60%{-webkit-transform:perspective(400px) rotateX(10deg);opacity:1;transform:perspective(400px) rotateX(10deg)}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-animation-name:flipInX;-webkit-backface-visibility:visible!important;animation-name:flipInX;backface-visibility:visible!important}@-webkit-keyframes flipInY{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateY(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);opacity:1;transform:perspective(400px) rotateY(10deg)}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(90deg);animation-timing-function:ease-in;opacity:0;transform:perspective(400px) rotateY(90deg)}40%{-webkit-animation-timing-function:ease-in;-webkit-transform:perspective(400px) rotateY(-20deg);animation-timing-function:ease-in;transform:perspective(400px) rotateY(-20deg)}60%{-webkit-transform:perspective(400px) rotateY(10deg);opacity:1;transform:perspective(400px) rotateY(10deg)}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-animation-name:flipInY;-webkit-backface-visibility:visible!important;animation-name:flipInY;backface-visibility:visible!important}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);opacity:1;transform:perspective(400px) rotateX(-20deg)}to{-webkit-transform:perspective(400px) rotateX(90deg);opacity:0;transform:perspective(400px) rotateX(90deg)}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);opacity:1;transform:perspective(400px) rotateX(-20deg)}to{-webkit-transform:perspective(400px) rotateX(90deg);opacity:0;transform:perspective(400px) rotateX(90deg)}}.flipOutX{-webkit-animation-duration:.75s;-webkit-animation-name:flipOutX;-webkit-backface-visibility:visible!important;animation-duration:.75s;animation-name:flipOutX;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);opacity:1;transform:perspective(400px) rotateY(-15deg)}to{-webkit-transform:perspective(400px) rotateY(90deg);opacity:0;transform:perspective(400px) rotateY(90deg)}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);opacity:1;transform:perspective(400px) rotateY(-15deg)}to{-webkit-transform:perspective(400px) rotateY(90deg);opacity:0;transform:perspective(400px) rotateY(90deg)}}.flipOutY{-webkit-animation-duration:.75s;-webkit-animation-name:flipOutY;-webkit-backface-visibility:visible!important;animation-duration:.75s;animation-name:flipOutY;backface-visibility:visible!important}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);opacity:0;transform:translate3d(100%,0,0) skewX(-30deg)}60%{-webkit-transform:skewX(20deg);opacity:1;transform:skewX(20deg)}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);opacity:0;transform:translate3d(100%,0,0) skewX(-30deg)}60%{-webkit-transform:skewX(20deg);opacity:1;transform:skewX(20deg)}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-name:lightSpeedIn;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);opacity:0;transform:translate3d(100%,0,0) skewX(30deg)}}@keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);opacity:0;transform:translate3d(100%,0,0) skewX(30deg)}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-name:lightSpeedOut;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(-200deg);transform-origin:center}to{-webkit-transform:translateZ(0);-webkit-transform-origin:center;opacity:1;transform:translateZ(0);transform-origin:center}}@keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(-200deg);transform-origin:center}to{-webkit-transform:translateZ(0);-webkit-transform-origin:center;opacity:1;transform:translateZ(0);transform-origin:center}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}@keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(45deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}@keyframes rotateInDownRight{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(45deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}@keyframes rotateInUpLeft{0%{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:left bottom;opacity:1;transform:translateZ(0);transform-origin:left bottom}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-90deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}@keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-90deg);transform-origin:right bottom}to{-webkit-transform:translateZ(0);-webkit-transform-origin:right bottom;opacity:1;transform:translateZ(0);transform-origin:right bottom}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;opacity:1;transform-origin:center}to{-webkit-transform:rotate(200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(200deg);transform-origin:center}}@keyframes rotateOut{0%{-webkit-transform-origin:center;opacity:1;transform-origin:center}to{-webkit-transform:rotate(200deg);-webkit-transform-origin:center;opacity:0;transform:rotate(200deg);transform-origin:center}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(45deg);transform-origin:left bottom}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-45deg);transform-origin:right bottom}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(-45deg);transform-origin:right bottom}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;opacity:1;transform-origin:left bottom}to{-webkit-transform:rotate(-45deg);-webkit-transform-origin:left bottom;opacity:0;transform:rotate(-45deg);transform-origin:left bottom}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(90deg);transform-origin:right bottom}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;opacity:1;transform-origin:right bottom}to{-webkit-transform:rotate(90deg);-webkit-transform-origin:right bottom;opacity:0;transform:rotate(90deg);transform-origin:right bottom}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-animation-timing-function:ease-in-out;-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform-origin:top left}20%,60%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(80deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(60deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;opacity:1;transform:rotate(60deg);transform-origin:top left}to{-webkit-transform:translate3d(0,700px,0);opacity:0;transform:translate3d(0,700px,0)}}@keyframes hinge{0%{-webkit-animation-timing-function:ease-in-out;-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform-origin:top left}20%,60%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(80deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;transform:rotate(80deg);transform-origin:top left}40%,80%{-webkit-animation-timing-function:ease-in-out;-webkit-transform:rotate(60deg);-webkit-transform-origin:top left;animation-timing-function:ease-in-out;opacity:1;transform:rotate(60deg);transform-origin:top left}to{-webkit-transform:translate3d(0,700px,0);opacity:0;transform:translate3d(0,700px,0)}}.hinge{-webkit-animation-duration:2s;-webkit-animation-name:hinge;animation-duration:2s;animation-name:hinge}@-webkit-keyframes jackInTheBox{0%{-webkit-transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;opacity:0;transform:scale(.1) rotate(30deg);transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{-webkit-transform:scale(1);opacity:1;transform:scale(1)}}@keyframes jackInTheBox{0%{-webkit-transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;opacity:0;transform:scale(.1) rotate(30deg);transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{-webkit-transform:scale(1);opacity:1;transform:scale(1)}}.jackInTheBox{-webkit-animation-name:jackInTheBox;animation-name:jackInTheBox}@-webkit-keyframes rollIn{0%{-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);opacity:0;transform:translate3d(-100%,0,0) rotate(-120deg)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}@keyframes rollIn{0%{-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);opacity:0;transform:translate3d(-100%,0,0) rotate(-120deg)}to{-webkit-transform:translateZ(0);opacity:1;transform:translateZ(0)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) rotate(120deg);opacity:0;transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) rotate(120deg);opacity:0;transform:translate3d(100%,0,0) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}}@keyframes zoomInDown{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(10px,0,0)}}@keyframes zoomInLeft{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(10px,0,0)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-10px,0,0)}}@keyframes zoomInRight{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(1000px,0,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-10px,0,0)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}}@keyframes zoomInUp{0%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,1000px,0)}60%{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{-webkit-transform:scale3d(.3,.3,.3);opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform-origin:center bottom}}@keyframes zoomOutDown{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,-60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform-origin:center bottom}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{-webkit-transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;opacity:0;transform:scale(.1) translate3d(-2000px,0,0);transform-origin:left center}}@keyframes zoomOutLeft{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{-webkit-transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;opacity:0;transform:scale(.1) translate3d(-2000px,0,0);transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{-webkit-transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;opacity:0;transform:scale(.1) translate3d(2000px,0,0);transform-origin:right center}}@keyframes zoomOutRight{40%{-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);opacity:1;transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{-webkit-transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;opacity:0;transform:scale(.1) translate3d(2000px,0,0);transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform-origin:center bottom}}@keyframes zoomOutUp{40%{-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);animation-timing-function:cubic-bezier(.55,.055,.675,.19);opacity:1;transform:scale3d(.475,.475,.475) translate3d(0,60px,0)}to{-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;animation-timing-function:cubic-bezier(.175,.885,.32,1);opacity:0;transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform-origin:center bottom}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:hidden}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:hidden}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:hidden}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:hidden}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:hidden}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:hidden}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:hidden}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:hidden}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}.animated{-webkit-animation-duration:1s;-webkit-animation-fill-mode:both;animation-duration:1s;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media (prefers-reduced-motion){.animated{-webkit-animation:unset!important;-webkit-transition:none!important;animation:unset!important;transition:none!important}} - - - /*! * Materialize v1.0.0 (http://materializecss.com) @@ -63,6 +60,7 @@ body,p{color:#8a8a8a;font-family:Roboto,-apple-system,system-ui,BlinkMacSystemFo body, p { font-family: Roboto,-apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif; color: #585858; + font-size: 13px; } h5 { font-size: 16px; @@ -76,6 +74,9 @@ table > thead > tr > th { td { word-break: break-all; } +.small, small { + font-size: 85%; +} /** * Topnav @@ -116,6 +117,7 @@ td { **/ .page-container .main-content { padding: 55px 0 0; + height: calc(100vh); min-height: calc(100vh); } .test-wrapper { @@ -155,6 +157,9 @@ td { **/ /* test list */ +.test-wrapper .test-list .test-list-wrapper .test-list-item .test-item { + padding: 10px 15px; +} .test-wrapper .test-list { background: #fff; } @@ -188,7 +193,7 @@ td { right: 20px; } .test-detail .name { - font-size: 14px !important; + font-size: 13px !important; font-weight: 500; word-break: break-all; width: 80%; @@ -210,7 +215,7 @@ td { padding: 0 16px 20px 16px; } .bdd-report .accordion .node { - font-size: 14px; + } .bdd-report .accordion .node-description { font-weight: 400; @@ -329,7 +334,6 @@ img.r-img { .node { display: inline-block; padding: 20px; - font-size: 14px; font-weight: 500; } .accordion > .card > .card-header > .card-title > a:not(.collapsed):after { @@ -428,7 +432,7 @@ img.r-img { * **/ -.dark .header { +.dark .header, body.dark { background-color: #08111c; } .dark .side-nav, .dark .test-list { @@ -438,11 +442,11 @@ img.r-img { .dark .test-wrapper { border: none; } -.dark .test-item, .dark .test-list-tools, .dark .header { +.dark .test-list-tools, .dark .header { border-bottom: 1px solid #19222d !important; } -.dark .table>thead>tr>th, .dark .table>tbody>tr>td { - border-bottom: 1px solid #494949; +.dark .test-item, .dark .table>thead>tr>th, .dark .table>tbody>tr>td { + border-bottom: 1px solid #494949 !important; } .dark .table>thead>tr>th, .dark .table>tbody>tr>td, .dark .card-footer, .dark td, .dark th { border-top: 1px solid #494949; @@ -450,7 +454,7 @@ img.r-img { .dark .test-item.active, .dark .test-item:hover { background-color: #19221c !important; } -.dark .test-detail .name { +.dark .test-detail .name, .dark p { color: rgba(141,164,191,.95) !important; } .dark .test-wrapper, .dark .test-content, .dark .dashboard-view .container-fluid { diff --git a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js index 2439ff5..c853841 100644 --- a/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js +++ b/src/main/resources/com/aventstack/extentreports/offline/spark/js/spark-script.js @@ -3,17 +3,12 @@ a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,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"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("