Repository: flask-dashboard/Flask-MonitoringDashboard (language: python)

Issue:
Support for Custom `get_ip` Injection
This PR adds support for a custom IP address getter.

It is not correct to use `REMOTE_ADDR` in every case, though it is a reasonable fallback. We achieve this by introducing a function called `inject_dependencies` inside the `Config` class. This is going to be useful for future PRs because it opens the door for a few other things, such as:

* Overriding `url_for` usage in favor of some user-defined logic (In our case, we have an application using a multi-host configuration, so we don't define `SERVER_NAME` in our Flask configuration, and `url_for` does not do the right thing)
* Decoupling the authentication layer completely from FMD in favor of user-defined functions to determine if:
  * There is a logged in user
  * There is a logged in admin

Awaiting your feedback!
Feature/micro service support
Basically I wanted the ability to not need scipy or the UI stuff so I could have a lightweight package to put on microservices. 

I added a setup_micro.py that only takes what I think we need - as well as flush_cache on teardown. 
The requirements are also truncated. 

Feature/micro service support
Basically I wanted the ability to not need scipy or the UI stuff so I could have a lightweight package to put on microservices. 

I added a setup_micro.py that only takes what I think we need - as well as flush_cache on teardown. 
The requirements are also truncated. 

Feature/micro service support
Basically I wanted the ability to not need scipy or the UI stuff so I could have a lightweight package to put on microservices. 

I added a setup_micro.py that only takes what I think we need - as well as flush_cache on teardown. 
The requirements are also truncated. 

Feature/micro service support
Basically I wanted the ability to not need scipy or the UI stuff so I could have a lightweight package to put on microservices. 

I added a setup_micro.py that only takes what I think we need - as well as flush_cache on teardown. 
The requirements are also truncated. 

Feature/micro service support
Basically I wanted the ability to not need scipy or the UI stuff so I could have a lightweight package to put on microservices. 

I added a setup_micro.py that only takes what I think we need - as well as flush_cache on teardown. 
The requirements are also truncated. 



Discussion / hints:

Fix patch:
diff --git a/config.cfg b/config.cfg
index 5a8cc86f6..a3b15750c 100644
--- a/config.cfg
+++ b/config.cfg
@@ -5,6 +5,11 @@ BLUEPRINT_NAME=dashboard
 CUSTOM_LINK=dashboard
 MONITOR_LEVEL=1
 OUTLIER_DETECTION_CONSTANT=2.5
+BRAND_NAME=Flask Monitoring Dashboard
+TITLE_NAME=Flask-MonitoringDashboard
+DESCRIPTION=Automatically monitor the evolving performance of Flask/Python web services
+SHOW_LOGIN_BANNER=True
+SHOW_LOGIN_FOOTER=True
 
 [authentication]
 USERNAME=admin
@@ -19,4 +24,4 @@ DATABASE=sqlite:////<path to your project>/dashboard.db
 [visualization]
 TIMEZONE=Europe/Amsterdam
 COLORS={'main':'[0,97,255]',
-        'static':'[255,153,0]'}
\ No newline at end of file
+        'static':'[255,153,0]'}
diff --git a/docs/configuration.rst b/docs/configuration.rst
index c4e8fd54b..a878fd026 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -60,6 +60,11 @@ file that contains the entry point of the app. The following properties can be c
    OUTLIER_DETECTION_CONSTANT=2.5
    SAMPLING_PERIOD=20
    ENABLE_LOGGING=True
+   BRAND_NAME=Flask Monitoring Dashboard
+   TITLE_NAME=Flask-MonitoringDashboard
+   DESCRIPTION=Automatically monitor the evolving performance of Flask/Python web services
+   SHOW_LOGIN_BANNER=True
+   SHOW_LOGIN_FOOTER=True
 
    [authentication]
    USERNAME=admin
@@ -103,6 +108,19 @@ Dashboard
 - **ENABLE_LOGGING:** Boolean if you want additional logs to be printed to the console. Default
   value is False.
 
+- **BRAND_NAME:** The name displayed in the Dashboard Navbar. Default value is 'Flask Monitoring Dashboard'.
+
+- **TITLE_NAME:** The name displayed in the browser tab. Default value is 'Flask-MonitoringDashboard'.
+
+- **DESCRIPTION:** The text displayed in center of the Dashboard Navbar. Default value is 
+  'Automatically monitor the evolving performance of Flask/Python web services'.
+
+- **SHOW_LOGIN_BANNER:** Boolean if you want the login page to show the 'Flask Monitoring Dashboard' logo and title. 
+  Default value is True.
+
+- **SHOW_LOGIN_FOOTER:** Boolean if you want the login page to show a link to the official documentation. 
+  Default value is True.
+
 Authentication
 ~~~~~~~~~~~~~~
 
diff --git a/flask_monitoringdashboard/__init__.py b/flask_monitoringdashboard/__init__.py
index 2e8c5c089..f98c9c758 100644
--- a/flask_monitoringdashboard/__init__.py
+++ b/flask_monitoringdashboard/__init__.py
@@ -29,12 +29,13 @@ def loc():
 blueprint = Blueprint('dashboard', __name__, template_folder=loc() + 'templates')
 
 
-def bind(app, schedule=True):
+def bind(app, schedule=True, include_dashboard=True):
     """Binding the app to this object should happen before importing the routing-
     methods below. Thus, the importing statement is part of this function.
 
     :param app: the app for which the performance has to be tracked
     :param schedule: flag telling if the background scheduler should be started
+    :param include_dashboard: flag telling if the views should be added or not.
     """
     blueprint.name = config.blueprint_name
     config.app = app
@@ -44,18 +45,19 @@ def bind(app, schedule=True):
         app.secret_key = 'my-secret-key'
 
     # Add all route-functions to the blueprint
-    from flask_monitoringdashboard.views import (
-        deployment,
-        custom,
-        endpoint,
-        outlier,
-        request,
-        profiler,
-        version,
-        auth,
-        reporting,
-    )
-    import flask_monitoringdashboard.views
+    if include_dashboard:
+        from flask_monitoringdashboard.views import (
+            deployment,
+            custom,
+            endpoint,
+            outlier,
+            request,
+            profiler,
+            version,
+            auth,
+            reporting,
+        )
+        import flask_monitoringdashboard.views
 
     # Add wrappers to the endpoints that have to be monitored
     from flask_monitoringdashboard.core.measurement import init_measurement
@@ -76,6 +78,11 @@ def bind(app, schedule=True):
 
     atexit.register(flush_cache)
 
+    if not include_dashboard:
+        @app.teardown_request
+        def teardown(_):
+            flush_cache()
+
 
 def add_graph(title, func, trigger="interval", **schedule):
     """Add a custom graph to the dashboard. You must specify the following arguments:
diff --git a/flask_monitoringdashboard/constants.json b/flask_monitoringdashboard/constants.json
index 665300c9e..b0b2c9709 100644
--- a/flask_monitoringdashboard/constants.json
+++ b/flask_monitoringdashboard/constants.json
@@ -1,5 +1,5 @@
 {
-    "version": "3.1.0",
+    "version": "3.1.1",
     "author": "Patrick Vogel, Bogdan Petre",
     "email": "flask.monitoringdashboard@gmail.com"
 }
\ No newline at end of file
diff --git a/flask_monitoringdashboard/controllers/endpoints.py b/flask_monitoringdashboard/controllers/endpoints.py
index db1bbfc70..e5f8a15ca 100644
--- a/flask_monitoringdashboard/controllers/endpoints.py
+++ b/flask_monitoringdashboard/controllers/endpoints.py
@@ -5,6 +5,7 @@
 
 from flask_monitoringdashboard import config
 from flask_monitoringdashboard.core import cache
+from flask_monitoringdashboard.core.blueprints import get_blueprint
 from flask_monitoringdashboard.core.colors import get_color
 from flask_monitoringdashboard.core.measurement import add_decorator
 from flask_monitoringdashboard.core.timezone import to_local_datetime, to_utc_datetime
@@ -60,6 +61,7 @@ def get_endpoint_overview(session):
         {
             'id': endpoint.id,
             'name': endpoint.name,
+            'blueprint': get_blueprint(endpoint.name),
             'monitor': endpoint.monitor_level,
             'color': get_color(endpoint.name),
             'hits-today': get_value(hits_today, endpoint.id),
diff --git a/flask_monitoringdashboard/core/blueprints.py b/flask_monitoringdashboard/core/blueprints.py
new file mode 100644
index 000000000..58d81eb79
--- /dev/null
+++ b/flask_monitoringdashboard/core/blueprints.py
@@ -0,0 +1,5 @@
+def get_blueprint(endpoint_name):
+    blueprint = endpoint_name
+    if '.' in endpoint_name:
+        blueprint = endpoint_name.split('.')[0]
+    return blueprint
diff --git a/flask_monitoringdashboard/core/config/__init__.py b/flask_monitoringdashboard/core/config/__init__.py
index f25e7d76f..910123b72 100644
--- a/flask_monitoringdashboard/core/config/__init__.py
+++ b/flask_monitoringdashboard/core/config/__init__.py
@@ -33,6 +33,11 @@ def __init__(self):
         self.outlier_detection_constant = 2.5
         self.sampling_period = 5 / 1000.0
         self.enable_logging = False
+        self.brand_name = 'Flask Monitoring Dashboard'
+        self.title_name = 'Flask-MonitoringDashboard'
+        self.description = 'Automatically monitor the evolving performance of Flask/Python web services'
+        self.show_login_banner = True
+        self.show_login_footer = True
 
         # database
         self.database_name = 'sqlite:///flask_monitoringdashboard.db'
@@ -57,6 +62,19 @@ def __init__(self):
         # store the Flask app
         self.app = None
 
+        # dependencies
+        self.get_ip = None
+
+    def inject_dependencies(self, get_ip=None):
+        """
+            Injects certain dependencies into the Monitoring Dashboard for better integration.
+            :param get_ip: a function that gets the appropriate client IP address inside a request
+                context. Overriding this allows you to provide the correct IP for logging purposes
+                in case your setup is running behind reverse proxies.
+        """
+        if get_ip:
+            self.get_ip = get_ip
+
     def init_from(self, file=None, envvar=None, log_verbose=False):
         """
             The config_file must at least contains the following variables in section 'dashboard':
@@ -75,6 +93,16 @@ def init_from(self, file=None, envvar=None, log_verbose=False):
                 If this value is not set, the profiler continuously monitors.
             - ENABLE_LOGGING: Boolean if you want additional logs to be printed to the console.
             Default value is False
+            - BRAND_NAME: The name displayed in the Dashboard Navbar. 
+            Default value is 'Flask Monitoring Dashboard'
+            - TITLE_NAME: The name displayed in the browser tab. 
+            Default value is 'Flask-MonitoringDashboard'
+            - DESCRIPTION: The text displayed in center of the Dashboard Navbar. 
+            Default value is 'Automatically monitor the evolving performance of Flask/Python web services'
+            - SHOW_LOGIN_BANNER: Boolean if you want the login page to show the 'Flask Monitoring Dashboard' logo and title. 
+            Default value is True
+            - SHOW_LOGIN_FOOTER: Boolean if you want the login page to show a link to the official documentation. 
+            Default value is True
 
             The config_file must at least contains the following variables in section
             'authentication':
@@ -138,6 +166,11 @@ def init_from(self, file=None, envvar=None, log_verbose=False):
             self.enable_logging = parse_bool(
                 parser, 'dashboard', 'ENABLE_LOGGING', self.enable_logging
             )
+            self.brand_name = parse_string(parser, 'dashboard', 'BRAND_NAME', self.brand_name)
+            self.title_name = parse_string(parser, 'dashboard', 'TITLE_NAME', self.title_name)
+            self.description = parse_string(parser, 'dashboard', 'DESCRIPTION', self.description)
+            self.show_login_banner = parse_bool(parser, 'dashboard', 'SHOW_LOGIN_BANNER', self.show_login_banner)
+            self.show_login_footer = parse_bool(parser, 'dashboard', 'SHOW_LOGIN_FOOTER', self.show_login_footer)
 
             # parse 'authentication'
             self.username = parse_string(parser, 'authentication', 'USERNAME', self.username)
diff --git a/flask_monitoringdashboard/core/get_ip.py b/flask_monitoringdashboard/core/get_ip.py
new file mode 100644
index 000000000..ddbd470b4
--- /dev/null
+++ b/flask_monitoringdashboard/core/get_ip.py
@@ -0,0 +1,16 @@
+from flask import request
+
+from flask_monitoringdashboard import config
+from flask_monitoringdashboard.core.logger import log
+
+def get_ip():
+    """
+    :return: the ip address associated with the current request context
+    """
+    if config.get_ip:
+        try:
+            return config.get_ip()
+        except Exception as e:
+            log('Failed to execute provided get_ip function: {}'.format(e))
+    # This is a reasonable fallback, but will not work for clients behind proxies.
+    return request.environ['REMOTE_ADDR']
diff --git a/flask_monitoringdashboard/core/profiler/__init__.py b/flask_monitoringdashboard/core/profiler/__init__.py
index 379cf908c..8cec57ce8 100644
--- a/flask_monitoringdashboard/core/profiler/__init__.py
+++ b/flask_monitoringdashboard/core/profiler/__init__.py
@@ -1,7 +1,6 @@
 import threading
 
-from flask import request
-
+from flask_monitoringdashboard.core.get_ip import get_ip
 from flask_monitoringdashboard.core.group_by import get_group_by
 from flask_monitoringdashboard.core.profiler.base_profiler import BaseProfiler
 from flask_monitoringdashboard.core.profiler.outlier_profiler import OutlierProfiler
@@ -24,17 +23,15 @@ def start_performance_thread(endpoint, duration, status_code):
     :param duration: duration of the request
     :param status_code: HTTP status code of the request
     """
-    ip = request.environ['REMOTE_ADDR']
     group_by = get_group_by()
-    PerformanceProfiler(endpoint, ip, duration, group_by, status_code).start()
+    PerformanceProfiler(endpoint, get_ip(), duration, group_by, status_code).start()
 
 
 def start_profiler_thread(endpoint):
     """ Starts a thread that profiles the main thread. """
     current_thread = threading.current_thread().ident
-    ip = request.environ['REMOTE_ADDR']
     group_by = get_group_by()
-    thread = StacktraceProfiler(current_thread, endpoint, ip, group_by)
+    thread = StacktraceProfiler(current_thread, endpoint, get_ip(), group_by)
     thread.start()
     return thread
 
@@ -42,9 +39,8 @@ def start_profiler_thread(endpoint):
 def start_outlier_thread(endpoint):
     """ Starts a thread that collects outliers."""
     current_thread = threading.current_thread().ident
-    ip = request.environ['REMOTE_ADDR']
     group_by = get_group_by()
-    thread = OutlierProfiler(current_thread, endpoint, ip, group_by)
+    thread = OutlierProfiler(current_thread, endpoint, get_ip(), group_by)
     thread.start()
     return thread
 
@@ -52,7 +48,7 @@ def start_outlier_thread(endpoint):
 def start_profiler_and_outlier_thread(endpoint):
     """ Starts two threads: PerformanceProfiler and StacktraceProfiler.  """
     current_thread = threading.current_thread().ident
-    ip = request.environ['REMOTE_ADDR']
+    ip = get_ip()
     group_by = get_group_by()
     outlier = OutlierProfiler(current_thread, endpoint, ip, group_by)
     thread = StacktraceProfiler(current_thread, endpoint, ip, group_by, outlier)
diff --git a/flask_monitoringdashboard/core/profiler/outlier_profiler.py b/flask_monitoringdashboard/core/profiler/outlier_profiler.py
index d0a448cb6..a203fd963 100644
--- a/flask_monitoringdashboard/core/profiler/outlier_profiler.py
+++ b/flask_monitoringdashboard/core/profiler/outlier_profiler.py
@@ -82,14 +82,13 @@ def stop(self, duration, status_code):
     def stop_by_profiler(self):
         self._exit.set()
 
-    def add_outlier(self, request_id):
+    def add_outlier(self, session, request_id):
         if self._memory:
-            with session_scope() as session:
-                add_outlier(
-                    session,
-                    request_id,
-                    self._cpu_percent,
-                    self._memory,
-                    self._stacktrace,
-                    self._request,
-                )
+            add_outlier(
+                session,
+                request_id,
+                self._cpu_percent,
+                self._memory,
+                self._stacktrace,
+                self._request,
+            )
diff --git a/flask_monitoringdashboard/core/profiler/stacktrace_profiler.py b/flask_monitoringdashboard/core/profiler/stacktrace_profiler.py
index 2eb4b1381..1863faa36 100644
--- a/flask_monitoringdashboard/core/profiler/stacktrace_profiler.py
+++ b/flask_monitoringdashboard/core/profiler/stacktrace_profiler.py
@@ -100,7 +100,7 @@ def _on_thread_stopped(self):
             self._lines_body = order_histogram(self._histogram.items())
             self.insert_lines_db(session, request_id)
             if self._outlier_profiler:
-                self._outlier_profiler.add_outlier(request_id)
+                self._outlier_profiler.add_outlier(session, request_id)
 
     def insert_lines_db(self, session, request_id):
         position = 0
diff --git a/flask_monitoringdashboard/frontend/js/controllers/OverviewController.js b/flask_monitoringdashboard/frontend/js/controllers/OverviewController.js
index 2b787a763..023f7baa3 100644
--- a/flask_monitoringdashboard/frontend/js/controllers/OverviewController.js
+++ b/flask_monitoringdashboard/frontend/js/controllers/OverviewController.js
@@ -12,12 +12,19 @@ export function OverviewController($scope, $http, $location, menuService, endpoi
     $scope.searchQuery = '';
     $scope.pageSize = '10';
     $scope.currentPage = 0;
+    $scope.blueprints = [''];
+    $scope.slectedBlueprint = '';
 
     $scope.toggleHits = function () {
         $scope.isHits = !$scope.isHits;
     };
 
     $http.get('api/overview').then(function (response) {
+        response.data.forEach((endpoint) => {
+            if (!$scope.blueprints.includes(endpoint.blueprint)) {
+                $scope.blueprints.push(endpoint.blueprint)
+            }
+        })
         $scope.table = response.data;
     });
 
@@ -25,9 +32,13 @@ export function OverviewController($scope, $http, $location, menuService, endpoi
         const start = Number(pageNumber) * $scope.pageSize;
         const end = (Number(pageNumber) + 1) * Number($scope.pageSize);
 
-        return $scope.table
+        let items = $scope.table
             .filter(item => item.name.includes($scope.searchQuery))
-            .slice(start, end);
+        if ($scope.slectedBlueprint) {
+            items = items.filter(item => item.blueprint===$scope.slectedBlueprint)
+        }
+
+        return items.slice(start, end);
     }
 
     $scope.getFilteredItems = function () {
diff --git a/flask_monitoringdashboard/frontend/js/controllers/reporting.js b/flask_monitoringdashboard/frontend/js/controllers/reporting.js
index cccbedbfa..6ca1206c3 100644
--- a/flask_monitoringdashboard/frontend/js/controllers/reporting.js
+++ b/flask_monitoringdashboard/frontend/js/controllers/reporting.js
@@ -51,7 +51,7 @@ export function ReportingController($scope, $http, menuService, endpointService,
 
     $scope.selectSection = function (section) {
         if (section === 'commits') {
-            $http.get('/dashboard/api/versions').then(function (response) {
+            $http.get('api/versions').then(function (response) {
                 $scope.versions = response.data;
             })
         }
@@ -103,12 +103,12 @@ export function ReportingController($scope, $http, menuService, endpointService,
 
         let promise;
         if ($scope.activeSection === 'commits') {
-            promise = $http.post('/dashboard/api/reporting/make_report/commits', {
+            promise = $http.post('api/reporting/make_report/commits', {
                 commit_version: $scope.commitVersion,
                 baseline_commit_version: $scope.baseLineCommitVersion,
             })
         } else {
-            promise = $http.post(`/dashboard/api/reporting/make_report/intervals`, {
+            promise = $http.post(`api/reporting/make_report/intervals`, {
                 interval: {
                     to: parseInt(`${$scope.intervals.comparison.to.getTime() / 1000}`),
                     from: parseInt(`${$scope.intervals.comparison.from.getTime() / 1000}`),
@@ -130,4 +130,4 @@ export function ReportingController($scope, $http, menuService, endpointService,
             $scope.generating = false;
         })
     };
-}
\ No newline at end of file
+}
diff --git a/flask_monitoringdashboard/frontend/package-lock.json b/flask_monitoringdashboard/frontend/package-lock.json
index b3daa942e..a44893ee7 100644
--- a/flask_monitoringdashboard/frontend/package-lock.json
+++ b/flask_monitoringdashboard/frontend/package-lock.json
@@ -141,14 +141,6 @@
         "resolve": "^1.3.2",
         "semver": "^5.4.1",
         "source-map": "^0.5.0"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
       }
     },
     "@babel/generator": {
@@ -249,14 +241,6 @@
         "@babel/helper-function-name": "^7.10.4",
         "@babel/types": "^7.10.5",
         "lodash": "^4.17.19"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
       }
     },
     "@babel/helper-explode-assignable-expression": {
@@ -329,14 +313,6 @@
         "@babel/template": "^7.10.4",
         "@babel/types": "^7.10.5",
         "lodash": "^4.17.19"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
       }
     },
     "@babel/helper-optimise-call-expression": {
@@ -361,14 +337,6 @@
       "dev": true,
       "requires": {
         "lodash": "^4.17.19"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
       }
     },
     "@babel/helper-remap-async-to-generator": {
@@ -1183,14 +1151,6 @@
         "debug": "^4.1.0",
         "globals": "^11.1.0",
         "lodash": "^4.17.19"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
       }
     },
     "@babel/types": {
@@ -1202,14 +1162,6 @@
         "@babel/helper-validator-identifier": "^7.10.4",
         "lodash": "^4.17.19",
         "to-fast-properties": "^2.0.0"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
-          "dev": true
-        }
       }
     },
     "@choojs/findup": {
@@ -2816,9 +2768,9 @@
       }
     },
     "bl": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
-      "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+      "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
       "requires": {
         "readable-stream": "^2.3.5",
         "safe-buffer": "^5.1.1"
@@ -3834,16 +3786,6 @@
             "uri-js": "^4.2.2"
           }
         },
-        "postcss": {
-          "version": "7.0.32",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
-          "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==",
-          "requires": {
-            "chalk": "^2.4.2",
-            "source-map": "^0.6.1",
-            "supports-color": "^6.1.0"
-          }
-        },
         "schema-utils": {
           "version": "2.7.0",
           "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
@@ -4493,18 +4435,26 @@
       }
     },
     "elliptic": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
-      "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
+      "version": "6.5.4",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+      "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
       "dev": true,
       "requires": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
+        "bn.js": "^4.11.9",
+        "brorand": "^1.1.0",
         "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
+        "hmac-drbg": "^1.0.1",
+        "inherits": "^2.0.4",
+        "minimalistic-assert": "^1.0.1",
+        "minimalistic-crypto-utils": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.12.0",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+          "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+          "dev": true
+        }
       }
     },
     "emoji-regex": {
@@ -6621,9 +6571,27 @@
       }
     },
     "hosted-git-info": {
-      "version": "2.8.8",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
-      "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
+      "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==",
+      "requires": {
+        "lru-cache": "^6.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        }
+      }
     },
     "hsluv": {
       "version": "0.0.3",
@@ -7425,9 +7393,9 @@
       }
     },
     "lodash": {
-      "version": "4.17.15",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
     },
     "log-symbols": {
       "version": "3.0.0",
@@ -8179,6 +8147,13 @@
         "resolve": "^1.10.0",
         "semver": "2 || 3 || 4 || 5",
         "validate-npm-package-license": "^3.0.1"
+      },
+      "dependencies": {
+        "hosted-git-info": {
+          "version": "2.8.9",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+        }
       }
     },
     "normalize-path": {
@@ -8234,14 +8209,6 @@
         "validate-npm-package-name": "^3.0.0"
       },
       "dependencies": {
-        "hosted-git-info": {
-          "version": "3.0.5",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz",
-          "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==",
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
         "lru-cache": {
           "version": "6.0.0",
           "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -8303,6 +8270,11 @@
         "safe-buffer": "^5.2.0"
       },
       "dependencies": {
+        "hosted-git-info": {
+          "version": "2.8.9",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+        },
         "lru-cache": {
           "version": "5.1.1",
           "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -8639,6 +8611,11 @@
         "which": "^1.3.1"
       },
       "dependencies": {
+        "hosted-git-info": {
+          "version": "2.8.9",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+        },
         "lru-cache": {
           "version": "5.1.1",
           "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -9154,9 +9131,9 @@
       "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
     },
     "postcss": {
-      "version": "7.0.27",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
-      "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+      "version": "7.0.36",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
+      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
       "requires": {
         "chalk": "^2.4.2",
         "source-map": "^0.6.1",
@@ -10548,9 +10525,9 @@
       }
     },
     "ssri": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
-      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
+      "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
       "requires": {
         "figgy-pudding": "^3.5.1"
       }
diff --git a/flask_monitoringdashboard/frontend/sass/custom.css b/flask_monitoringdashboard/frontend/sass/custom.css
index e679e244f..0438aa791 100644
--- a/flask_monitoringdashboard/frontend/sass/custom.css
+++ b/flask_monitoringdashboard/frontend/sass/custom.css
@@ -507,4 +507,10 @@ footer.sticky-footer {
     color: red;
     vertical-align: super;
     font-size: small;
+}
+
+@media (min-width: 1644px) {
+    .container {
+        max-width: 1600px !important;
+    }
 }
\ No newline at end of file
diff --git a/flask_monitoringdashboard/static/elements/monitorLevel.html b/flask_monitoringdashboard/static/elements/monitorLevel.html
index 66f7b9d3b..330d7f8e0 100644
--- a/flask_monitoringdashboard/static/elements/monitorLevel.html
+++ b/flask_monitoringdashboard/static/elements/monitorLevel.html
@@ -1,4 +1,4 @@
-<ul class="pagination">
+<ul class="pagination mb-0 ml-2">
     <li ng-repeat="n in [0, 1, 2, 3]" class="page-item">
         <a class="page-link" ng-click="sendForm(n)"
            ng-style="{'background-color': computeColor(n),
diff --git a/flask_monitoringdashboard/static/js/app.js b/flask_monitoringdashboard/static/js/app.js
index 6b9ef7fe8..9330aba78 100644
--- a/flask_monitoringdashboard/static/js/app.js
+++ b/flask_monitoringdashboard/static/js/app.js
@@ -67,4 +67,4 @@ var r,a=e("./lib/build-log"),i=e("./lib/epsilon"),o=e("./lib/intersecter"),s=e("
   * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
   */
-!function(e,t,n){"use strict";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function a(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e){var n=this,r=!1;return t(this).one(c.TRANSITION_END,(function(){r=!0})),setTimeout((function(){r||c.triggerTransitionEnd(n)}),e),this}t=t&&t.hasOwnProperty("default")?t.default:t,n=n&&n.hasOwnProperty("default")?n.default:n;var c={TRANSITION_END:"bsTransitionEnd",getUID:function(e){do{e+=~~(1e6*Math.random())}while(document.getElementById(e));return e},getSelectorFromElement:function(e){var t=e.getAttribute("data-target");if(!t||"#"===t){var n=e.getAttribute("href");t=n&&"#"!==n?n.trim():""}try{return document.querySelector(t)?t:null}catch(e){return null}},getTransitionDurationFromElement:function(e){if(!e)return 0;var n=t(e).css("transition-duration"),r=t(e).css("transition-delay"),a=parseFloat(n),i=parseFloat(r);return a||i?(n=n.split(",")[0],r=r.split(",")[0],1e3*(parseFloat(n)+parseFloat(r))):0},reflow:function(e){return e.offsetHeight},triggerTransitionEnd:function(e){t(e).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(e){return(e[0]||e).nodeType},typeCheckConfig:function(e,t,n){for(var r in n)if(Object.prototype.hasOwnProperty.call(n,r)){var a=n[r],i=t[r],o=i&&c.isElement(i)?"element":(s=i,{}.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase());if(!new RegExp(a).test(o))throw new Error(e.toUpperCase()+': Option "'+r+'" provided type "'+o+'" but expected type "'+a+'".')}var s},findShadowRoot:function(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?c.findShadowRoot(e.parentNode):null},jQueryDetection:function(){if(void 0===t)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1===e[0]&&9===e[1]&&e[2]<1||e[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};c.jQueryDetection(),t.fn.emulateTransitionEnd=l,t.event.special[c.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(e){if(t(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}};var u="alert",d=t.fn[u],f={CLOSE:"close.bs.alert",CLOSED:"closed.bs.alert",CLICK_DATA_API:"click.bs.alert.data-api"},h="alert",p="fade",m="show",g=function(){function e(e){this._element=e}var n=e.prototype;return n.close=function(e){var t=this._element;e&&(t=this._getRootElement(e)),this._triggerCloseEvent(t).isDefaultPrevented()||this._removeElement(t)},n.dispose=function(){t.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(e){var n=c.getSelectorFromElement(e),r=!1;return n&&(r=document.querySelector(n)),r||(r=t(e).closest("."+h)[0]),r},n._triggerCloseEvent=function(e){var n=t.Event(f.CLOSE);return t(e).trigger(n),n},n._removeElement=function(e){var n=this;if(t(e).removeClass(m),t(e).hasClass(p)){var r=c.getTransitionDurationFromElement(e);t(e).one(c.TRANSITION_END,(function(t){return n._destroyElement(e,t)})).emulateTransitionEnd(r)}else this._destroyElement(e)},n._destroyElement=function(e){t(e).detach().trigger(f.CLOSED).remove()},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.alert");a||(a=new e(this),r.data("bs.alert",a)),"close"===n&&a[n](this)}))},e._handleDismiss=function(e){return function(t){t&&t.preventDefault(),e.close(this)}},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}}]),e}();t(document).on(f.CLICK_DATA_API,'[data-dismiss="alert"]',g._handleDismiss(new g)),t.fn[u]=g._jQueryInterface,t.fn[u].Constructor=g,t.fn[u].noConflict=function(){return t.fn[u]=d,g._jQueryInterface};var y=t.fn.button,_="active",v="btn",x="focus",b='[data-toggle^="button"]',M='[data-toggle="buttons"]',w='[data-toggle="button"]',k='[data-toggle="buttons"] .btn',T='input:not([type="hidden"])',L=".active",D=".btn",A={CLICK_DATA_API:"click.bs.button.data-api",FOCUS_BLUR_DATA_API:"focus.bs.button.data-api blur.bs.button.data-api",LOAD_DATA_API:"load.bs.button.data-api"},S=function(){function e(e){this._element=e}var n=e.prototype;return n.toggle=function(){var e=!0,n=!0,r=t(this._element).closest(M)[0];if(r){var a=this._element.querySelector(T);if(a){if("radio"===a.type)if(a.checked&&this._element.classList.contains(_))e=!1;else{var i=r.querySelector(L);i&&t(i).removeClass(_)}else"checkbox"===a.type?"LABEL"===this._element.tagName&&a.checked===this._element.classList.contains(_)&&(e=!1):e=!1;e&&(a.checked=!this._element.classList.contains(_),t(a).trigger("change")),a.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(_)),e&&t(this._element).toggleClass(_))},n.dispose=function(){t.removeData(this._element,"bs.button"),this._element=null},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.button");r||(r=new e(this),t(this).data("bs.button",r)),"toggle"===n&&r[n]()}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}}]),e}();t(document).on(A.CLICK_DATA_API,b,(function(e){var n=e.target;if(t(n).hasClass(v)||(n=t(n).closest(D)[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))e.preventDefault();else{var r=n.querySelector(T);if(r&&(r.hasAttribute("disabled")||r.classList.contains("disabled")))return void e.preventDefault();S._jQueryInterface.call(t(n),"toggle")}})).on(A.FOCUS_BLUR_DATA_API,b,(function(e){var n=t(e.target).closest(D)[0];t(n).toggleClass(x,/^focus(in)?$/.test(e.type))})),t(window).on(A.LOAD_DATA_API,(function(){for(var e=[].slice.call(document.querySelectorAll(k)),t=0,n=e.length;t<n;t++){var r=e[t],a=r.querySelector(T);a.checked||a.hasAttribute("checked")?r.classList.add(_):r.classList.remove(_)}for(var i=0,o=(e=[].slice.call(document.querySelectorAll(w))).length;i<o;i++){var s=e[i];"true"===s.getAttribute("aria-pressed")?s.classList.add(_):s.classList.remove(_)}})),t.fn.button=S._jQueryInterface,t.fn.button.Constructor=S,t.fn.button.noConflict=function(){return t.fn.button=y,S._jQueryInterface};var Y="carousel",C=".bs.carousel",O=t.fn[Y],E={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},P={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},H="next",j="prev",z="left",I="right",N={SLIDE:"slide"+C,SLID:"slid"+C,KEYDOWN:"keydown"+C,MOUSEENTER:"mouseenter"+C,MOUSELEAVE:"mouseleave"+C,TOUCHSTART:"touchstart"+C,TOUCHMOVE:"touchmove"+C,TOUCHEND:"touchend"+C,POINTERDOWN:"pointerdown"+C,POINTERUP:"pointerup"+C,DRAG_START:"dragstart"+C,LOAD_DATA_API:"load"+C+".data-api",CLICK_DATA_API:"click"+C+".data-api"},F="carousel",R="active",W="slide",B="carousel-item-right",q="carousel-item-left",V="carousel-item-next",U="carousel-item-prev",G="pointer-event",J=".active",Z=".active.carousel-item",$=".carousel-item",X=".carousel-item img",K=".carousel-item-next, .carousel-item-prev",Q=".carousel-indicators",ee="[data-slide], [data-slide-to]",te='[data-ride="carousel"]',ne={TOUCH:"touch",PEN:"pen"},re=function(){function e(e,t){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(t),this._element=e,this._indicatorsElement=this._element.querySelector(Q),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=e.prototype;return n.next=function(){this._isSliding||this._slide(H)},n.nextWhenVisible=function(){!document.hidden&&t(this._element).is(":visible")&&"hidden"!==t(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide(j)},n.pause=function(e){e||(this._isPaused=!0),this._element.querySelector(K)&&(c.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(e){e||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(e){var n=this;this._activeElement=this._element.querySelector(Z);var r=this._getItemIndex(this._activeElement);if(!(e>this._items.length-1||e<0))if(this._isSliding)t(this._element).one(N.SLID,(function(){return n.to(e)}));else{if(r===e)return this.pause(),void this.cycle();var a=e>r?H:j;this._slide(a,this._items[e])}},n.dispose=function(){t(this._element).off(C),t.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(e){return e=s({},E,{},e),c.typeCheckConfig(Y,e,P),e},n._handleSwipe=function(){var e=Math.abs(this.touchDeltaX);if(!(e<=40)){var t=e/this.touchDeltaX;this.touchDeltaX=0,t>0&&this.prev(),t<0&&this.next()}},n._addEventListeners=function(){var e=this;this._config.keyboard&&t(this._element).on(N.KEYDOWN,(function(t){return e._keydown(t)})),"hover"===this._config.pause&&t(this._element).on(N.MOUSEENTER,(function(t){return e.pause(t)})).on(N.MOUSELEAVE,(function(t){return e.cycle(t)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var e=this;if(this._touchSupported){var n=function(t){e._pointerEvent&&ne[t.originalEvent.pointerType.toUpperCase()]?e.touchStartX=t.originalEvent.clientX:e._pointerEvent||(e.touchStartX=t.originalEvent.touches[0].clientX)},r=function(t){e._pointerEvent&&ne[t.originalEvent.pointerType.toUpperCase()]&&(e.touchDeltaX=t.originalEvent.clientX-e.touchStartX),e._handleSwipe(),"hover"===e._config.pause&&(e.pause(),e.touchTimeout&&clearTimeout(e.touchTimeout),e.touchTimeout=setTimeout((function(t){return e.cycle(t)}),500+e._config.interval))};t(this._element.querySelectorAll(X)).on(N.DRAG_START,(function(e){return e.preventDefault()})),this._pointerEvent?(t(this._element).on(N.POINTERDOWN,(function(e){return n(e)})),t(this._element).on(N.POINTERUP,(function(e){return r(e)})),this._element.classList.add(G)):(t(this._element).on(N.TOUCHSTART,(function(e){return n(e)})),t(this._element).on(N.TOUCHMOVE,(function(t){return function(t){t.originalEvent.touches&&t.originalEvent.touches.length>1?e.touchDeltaX=0:e.touchDeltaX=t.originalEvent.touches[0].clientX-e.touchStartX}(t)})),t(this._element).on(N.TOUCHEND,(function(e){return r(e)})))}},n._keydown=function(e){if(!/input|textarea/i.test(e.target.tagName))switch(e.which){case 37:e.preventDefault(),this.prev();break;case 39:e.preventDefault(),this.next()}},n._getItemIndex=function(e){return this._items=e&&e.parentNode?[].slice.call(e.parentNode.querySelectorAll($)):[],this._items.indexOf(e)},n._getItemByDirection=function(e,t){var n=e===H,r=e===j,a=this._getItemIndex(t),i=this._items.length-1;if((r&&0===a||n&&a===i)&&!this._config.wrap)return t;var o=(a+(e===j?-1:1))%this._items.length;return-1===o?this._items[this._items.length-1]:this._items[o]},n._triggerSlideEvent=function(e,n){var r=this._getItemIndex(e),a=this._getItemIndex(this._element.querySelector(Z)),i=t.Event(N.SLIDE,{relatedTarget:e,direction:n,from:a,to:r});return t(this._element).trigger(i),i},n._setActiveIndicatorElement=function(e){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(J));t(n).removeClass(R);var r=this._indicatorsElement.children[this._getItemIndex(e)];r&&t(r).addClass(R)}},n._slide=function(e,n){var r,a,i,o=this,s=this._element.querySelector(Z),l=this._getItemIndex(s),u=n||s&&this._getItemByDirection(e,s),d=this._getItemIndex(u),f=Boolean(this._interval);if(e===H?(r=q,a=V,i=z):(r=B,a=U,i=I),u&&t(u).hasClass(R))this._isSliding=!1;else if(!this._triggerSlideEvent(u,i).isDefaultPrevented()&&s&&u){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(u);var h=t.Event(N.SLID,{relatedTarget:u,direction:i,from:l,to:d});if(t(this._element).hasClass(W)){t(u).addClass(a),c.reflow(u),t(s).addClass(r),t(u).addClass(r);var p=parseInt(u.getAttribute("data-interval"),10);p?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=p):this._config.interval=this._config.defaultInterval||this._config.interval;var m=c.getTransitionDurationFromElement(s);t(s).one(c.TRANSITION_END,(function(){t(u).removeClass(r+" "+a).addClass(R),t(s).removeClass(R+" "+a+" "+r),o._isSliding=!1,setTimeout((function(){return t(o._element).trigger(h)}),0)})).emulateTransitionEnd(m)}else t(s).removeClass(R),t(u).addClass(R),this._isSliding=!1,t(this._element).trigger(h);f&&this.cycle()}},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.carousel"),a=s({},E,{},t(this).data());"object"==typeof n&&(a=s({},a,{},n));var i="string"==typeof n?n:a.slide;if(r||(r=new e(this,a),t(this).data("bs.carousel",r)),"number"==typeof n)r.to(n);else if("string"==typeof i){if(void 0===r[i])throw new TypeError('No method named "'+i+'"');r[i]()}else a.interval&&a.ride&&(r.pause(),r.cycle())}))},e._dataApiClickHandler=function(n){var r=c.getSelectorFromElement(this);if(r){var a=t(r)[0];if(a&&t(a).hasClass(F)){var i=s({},t(a).data(),{},t(this).data()),o=this.getAttribute("data-slide-to");o&&(i.interval=!1),e._jQueryInterface.call(t(a),i),o&&t(a).data("bs.carousel").to(o),n.preventDefault()}}},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return E}}]),e}();t(document).on(N.CLICK_DATA_API,ee,re._dataApiClickHandler),t(window).on(N.LOAD_DATA_API,(function(){for(var e=[].slice.call(document.querySelectorAll(te)),n=0,r=e.length;n<r;n++){var a=t(e[n]);re._jQueryInterface.call(a,a.data())}})),t.fn[Y]=re._jQueryInterface,t.fn[Y].Constructor=re,t.fn[Y].noConflict=function(){return t.fn[Y]=O,re._jQueryInterface};var ae="collapse",ie=t.fn[ae],oe={toggle:!0,parent:""},se={toggle:"boolean",parent:"(string|element)"},le={SHOW:"show.bs.collapse",SHOWN:"shown.bs.collapse",HIDE:"hide.bs.collapse",HIDDEN:"hidden.bs.collapse",CLICK_DATA_API:"click.bs.collapse.data-api"},ce="show",ue="collapse",de="collapsing",fe="collapsed",he="width",pe="height",me=".show, .collapsing",ge='[data-toggle="collapse"]',ye=function(){function e(e,t){this._isTransitioning=!1,this._element=e,this._config=this._getConfig(t),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'));for(var n=[].slice.call(document.querySelectorAll(ge)),r=0,a=n.length;r<a;r++){var i=n[r],o=c.getSelectorFromElement(i),s=[].slice.call(document.querySelectorAll(o)).filter((function(t){return t===e}));null!==o&&s.length>0&&(this._selector=o,this._triggerArray.push(i))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=e.prototype;return n.toggle=function(){t(this._element).hasClass(ce)?this.hide():this.show()},n.show=function(){var n,r,a=this;if(!(this._isTransitioning||t(this._element).hasClass(ce)||(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(me)).filter((function(e){return"string"==typeof a._config.parent?e.getAttribute("data-parent")===a._config.parent:e.classList.contains(ue)}))).length&&(n=null),n&&(r=t(n).not(this._selector).data("bs.collapse"))&&r._isTransitioning))){var i=t.Event(le.SHOW);if(t(this._element).trigger(i),!i.isDefaultPrevented()){n&&(e._jQueryInterface.call(t(n).not(this._selector),"hide"),r||t(n).data("bs.collapse",null));var o=this._getDimension();t(this._element).removeClass(ue).addClass(de),this._element.style[o]=0,this._triggerArray.length&&t(this._triggerArray).removeClass(fe).attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(o[0].toUpperCase()+o.slice(1)),l=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(){t(a._element).removeClass(de).addClass(ue).addClass(ce),a._element.style[o]="",a.setTransitioning(!1),t(a._element).trigger(le.SHOWN)})).emulateTransitionEnd(l),this._element.style[o]=this._element[s]+"px"}}},n.hide=function(){var e=this;if(!this._isTransitioning&&t(this._element).hasClass(ce)){var n=t.Event(le.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var r=this._getDimension();this._element.style[r]=this._element.getBoundingClientRect()[r]+"px",c.reflow(this._element),t(this._element).addClass(de).removeClass(ue).removeClass(ce);var a=this._triggerArray.length;if(a>0)for(var i=0;i<a;i++){var o=this._triggerArray[i],s=c.getSelectorFromElement(o);null!==s&&(t([].slice.call(document.querySelectorAll(s))).hasClass(ce)||t(o).addClass(fe).attr("aria-expanded",!1))}this.setTransitioning(!0),this._element.style[r]="";var l=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(){e.setTransitioning(!1),t(e._element).removeClass(de).addClass(ue).trigger(le.HIDDEN)})).emulateTransitionEnd(l)}}},n.setTransitioning=function(e){this._isTransitioning=e},n.dispose=function(){t.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(e){return(e=s({},oe,{},e)).toggle=Boolean(e.toggle),c.typeCheckConfig(ae,e,se),e},n._getDimension=function(){return t(this._element).hasClass(he)?he:pe},n._getParent=function(){var n,r=this;c.isElement(this._config.parent)?(n=this._config.parent,void 0!==this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var a='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',i=[].slice.call(n.querySelectorAll(a));return t(i).each((function(t,n){r._addAriaAndCollapsedClass(e._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(e,n){var r=t(e).hasClass(ce);n.length&&t(n).toggleClass(fe,!r).attr("aria-expanded",r)},e._getTargetFromElement=function(e){var t=c.getSelectorFromElement(e);return t?document.querySelector(t):null},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.collapse"),i=s({},oe,{},r.data(),{},"object"==typeof n&&n?n:{});if(!a&&i.toggle&&/show|hide/.test(n)&&(i.toggle=!1),a||(a=new e(this,i),r.data("bs.collapse",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return oe}}]),e}();t(document).on(le.CLICK_DATA_API,ge,(function(e){"A"===e.currentTarget.tagName&&e.preventDefault();var n=t(this),r=c.getSelectorFromElement(this),a=[].slice.call(document.querySelectorAll(r));t(a).each((function(){var e=t(this),r=e.data("bs.collapse")?"toggle":n.data();ye._jQueryInterface.call(e,r)}))})),t.fn[ae]=ye._jQueryInterface,t.fn[ae].Constructor=ye,t.fn[ae].noConflict=function(){return t.fn[ae]=ie,ye._jQueryInterface};var _e="dropdown",ve=t.fn[_e],xe=new RegExp("38|40|27"),be={HIDE:"hide.bs.dropdown",HIDDEN:"hidden.bs.dropdown",SHOW:"show.bs.dropdown",SHOWN:"shown.bs.dropdown",CLICK:"click.bs.dropdown",CLICK_DATA_API:"click.bs.dropdown.data-api",KEYDOWN_DATA_API:"keydown.bs.dropdown.data-api",KEYUP_DATA_API:"keyup.bs.dropdown.data-api"},Me="disabled",we="show",ke="dropup",Te="dropright",Le="dropleft",De="dropdown-menu-right",Ae="position-static",Se='[data-toggle="dropdown"]',Ye=".dropdown form",Ce=".dropdown-menu",Oe=".navbar-nav",Ee=".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",Pe="top-start",He="top-end",je="bottom-start",ze="bottom-end",Ie="right-start",Ne="left-start",Fe={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Re={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},We=function(){function e(e,t){this._element=e,this._popper=null,this._config=this._getConfig(t),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var r=e.prototype;return r.toggle=function(){if(!this._element.disabled&&!t(this._element).hasClass(Me)){var n=t(this._menu).hasClass(we);e._clearMenus(),n||this.show(!0)}},r.show=function(r){if(void 0===r&&(r=!1),!(this._element.disabled||t(this._element).hasClass(Me)||t(this._menu).hasClass(we))){var a={relatedTarget:this._element},i=t.Event(be.SHOW,a),o=e._getParentFromElement(this._element);if(t(o).trigger(i),!i.isDefaultPrevented()){if(!this._inNavbar&&r){if(void 0===n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var s=this._element;"parent"===this._config.reference?s=o:c.isElement(this._config.reference)&&(s=this._config.reference,void 0!==this._config.reference.jquery&&(s=this._config.reference[0])),"scrollParent"!==this._config.boundary&&t(o).addClass(Ae),this._popper=new n(s,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===t(o).closest(Oe).length&&t(document.body).children().on("mouseover",null,t.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),t(this._menu).toggleClass(we),t(o).toggleClass(we).trigger(t.Event(be.SHOWN,a))}}},r.hide=function(){if(!this._element.disabled&&!t(this._element).hasClass(Me)&&t(this._menu).hasClass(we)){var n={relatedTarget:this._element},r=t.Event(be.HIDE,n),a=e._getParentFromElement(this._element);t(a).trigger(r),r.isDefaultPrevented()||(this._popper&&this._popper.destroy(),t(this._menu).toggleClass(we),t(a).toggleClass(we).trigger(t.Event(be.HIDDEN,n)))}},r.dispose=function(){t.removeData(this._element,"bs.dropdown"),t(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},r.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},r._addEventListeners=function(){var e=this;t(this._element).on(be.CLICK,(function(t){t.preventDefault(),t.stopPropagation(),e.toggle()}))},r._getConfig=function(e){return e=s({},this.constructor.Default,{},t(this._element).data(),{},e),c.typeCheckConfig(_e,e,this.constructor.DefaultType),e},r._getMenuElement=function(){if(!this._menu){var t=e._getParentFromElement(this._element);t&&(this._menu=t.querySelector(Ce))}return this._menu},r._getPlacement=function(){var e=t(this._element.parentNode),n=je;return e.hasClass(ke)?(n=Pe,t(this._menu).hasClass(De)&&(n=He)):e.hasClass(Te)?n=Ie:e.hasClass(Le)?n=Ne:t(this._menu).hasClass(De)&&(n=ze),n},r._detectNavbar=function(){return t(this._element).closest(".navbar").length>0},r._getOffset=function(){var e=this,t={};return"function"==typeof this._config.offset?t.fn=function(t){return t.offsets=s({},t.offsets,{},e._config.offset(t.offsets,e._element)||{}),t}:t.offset=this._config.offset,t},r._getPopperConfig=function(){var e={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(e.modifiers.applyStyle={enabled:!1}),s({},e,{},this._config.popperConfig)},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.dropdown");if(r||(r=new e(this,"object"==typeof n?n:null),t(this).data("bs.dropdown",r)),"string"==typeof n){if(void 0===r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},e._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var r=[].slice.call(document.querySelectorAll(Se)),a=0,i=r.length;a<i;a++){var o=e._getParentFromElement(r[a]),s=t(r[a]).data("bs.dropdown"),l={relatedTarget:r[a]};if(n&&"click"===n.type&&(l.clickEvent=n),s){var c=s._menu;if(t(o).hasClass(we)&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&t.contains(o,n.target))){var u=t.Event(be.HIDE,l);t(o).trigger(u),u.isDefaultPrevented()||("ontouchstart"in document.documentElement&&t(document.body).children().off("mouseover",null,t.noop),r[a].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),t(c).removeClass(we),t(o).removeClass(we).trigger(t.Event(be.HIDDEN,l)))}}}},e._getParentFromElement=function(e){var t,n=c.getSelectorFromElement(e);return n&&(t=document.querySelector(n)),t||e.parentNode},e._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||t(n.target).closest(Ce).length):!xe.test(n.which))&&(n.preventDefault(),n.stopPropagation(),!this.disabled&&!t(this).hasClass(Me))){var r=e._getParentFromElement(this),a=t(r).hasClass(we);if(a||27!==n.which)if(a&&(!a||27!==n.which&&32!==n.which)){var i=[].slice.call(r.querySelectorAll(Ee)).filter((function(e){return t(e).is(":visible")}));if(0!==i.length){var o=i.indexOf(n.target);38===n.which&&o>0&&o--,40===n.which&&o<i.length-1&&o++,o<0&&(o=0),i[o].focus()}}else{if(27===n.which){var s=r.querySelector(Se);t(s).trigger("focus")}t(this).trigger("click")}}},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return Fe}},{key:"DefaultType",get:function(){return Re}}]),e}();t(document).on(be.KEYDOWN_DATA_API,Se,We._dataApiKeydownHandler).on(be.KEYDOWN_DATA_API,Ce,We._dataApiKeydownHandler).on(be.CLICK_DATA_API+" "+be.KEYUP_DATA_API,We._clearMenus).on(be.CLICK_DATA_API,Se,(function(e){e.preventDefault(),e.stopPropagation(),We._jQueryInterface.call(t(this),"toggle")})).on(be.CLICK_DATA_API,Ye,(function(e){e.stopPropagation()})),t.fn[_e]=We._jQueryInterface,t.fn[_e].Constructor=We,t.fn[_e].noConflict=function(){return t.fn[_e]=ve,We._jQueryInterface};var Be=t.fn.modal,qe={backdrop:!0,keyboard:!0,focus:!0,show:!0},Ve={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Ue={HIDE:"hide.bs.modal",HIDE_PREVENTED:"hidePrevented.bs.modal",HIDDEN:"hidden.bs.modal",SHOW:"show.bs.modal",SHOWN:"shown.bs.modal",FOCUSIN:"focusin.bs.modal",RESIZE:"resize.bs.modal",CLICK_DISMISS:"click.dismiss.bs.modal",KEYDOWN_DISMISS:"keydown.dismiss.bs.modal",MOUSEUP_DISMISS:"mouseup.dismiss.bs.modal",MOUSEDOWN_DISMISS:"mousedown.dismiss.bs.modal",CLICK_DATA_API:"click.bs.modal.data-api"},Ge="modal-dialog-scrollable",Je="modal-scrollbar-measure",Ze="modal-backdrop",$e="modal-open",Xe="fade",Ke="show",Qe="modal-static",et=".modal-dialog",tt=".modal-body",nt='[data-toggle="modal"]',rt='[data-dismiss="modal"]',at=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",it=".sticky-top",ot=function(){function e(e,t){this._config=this._getConfig(t),this._element=e,this._dialog=e.querySelector(et),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=e.prototype;return n.toggle=function(e){return this._isShown?this.hide():this.show(e)},n.show=function(e){var n=this;if(!this._isShown&&!this._isTransitioning){t(this._element).hasClass(Xe)&&(this._isTransitioning=!0);var r=t.Event(Ue.SHOW,{relatedTarget:e});t(this._element).trigger(r),this._isShown||r.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),t(this._element).on(Ue.CLICK_DISMISS,rt,(function(e){return n.hide(e)})),t(this._dialog).on(Ue.MOUSEDOWN_DISMISS,(function(){t(n._element).one(Ue.MOUSEUP_DISMISS,(function(e){t(e.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(e)})))}},n.hide=function(e){var n=this;if(e&&e.preventDefault(),this._isShown&&!this._isTransitioning){var r=t.Event(Ue.HIDE);if(t(this._element).trigger(r),this._isShown&&!r.isDefaultPrevented()){this._isShown=!1;var a=t(this._element).hasClass(Xe);if(a&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),t(document).off(Ue.FOCUSIN),t(this._element).removeClass(Ke),t(this._element).off(Ue.CLICK_DISMISS),t(this._dialog).off(Ue.MOUSEDOWN_DISMISS),a){var i=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(e){return n._hideModal(e)})).emulateTransitionEnd(i)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(e){return t(e).off(".bs.modal")})),t(document).off(Ue.FOCUSIN),t.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(e){return e=s({},qe,{},e),c.typeCheckConfig("modal",e,Ve),e},n._triggerBackdropTransition=function(){var e=this;if("static"===this._config.backdrop){var n=t.Event(Ue.HIDE_PREVENTED);if(t(this._element).trigger(n),n.defaultPrevented)return;this._element.classList.add(Qe);var r=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(){e._element.classList.remove(Qe)})).emulateTransitionEnd(r),this._element.focus()}else this.hide()},n._showElement=function(e){var n=this,r=t(this._element).hasClass(Xe),a=this._dialog?this._dialog.querySelector(tt):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),t(this._dialog).hasClass(Ge)&&a?a.scrollTop=0:this._element.scrollTop=0,r&&c.reflow(this._element),t(this._element).addClass(Ke),this._config.focus&&this._enforceFocus();var i=t.Event(Ue.SHOWN,{relatedTarget:e}),o=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,t(n._element).trigger(i)};if(r){var s=c.getTransitionDurationFromElement(this._dialog);t(this._dialog).one(c.TRANSITION_END,o).emulateTransitionEnd(s)}else o()},n._enforceFocus=function(){var e=this;t(document).off(Ue.FOCUSIN).on(Ue.FOCUSIN,(function(n){document!==n.target&&e._element!==n.target&&0===t(e._element).has(n.target).length&&e._element.focus()}))},n._setEscapeEvent=function(){var e=this;this._isShown&&this._config.keyboard?t(this._element).on(Ue.KEYDOWN_DISMISS,(function(t){27===t.which&&e._triggerBackdropTransition()})):this._isShown||t(this._element).off(Ue.KEYDOWN_DISMISS)},n._setResizeEvent=function(){var e=this;this._isShown?t(window).on(Ue.RESIZE,(function(t){return e.handleUpdate(t)})):t(window).off(Ue.RESIZE)},n._hideModal=function(){var e=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._isTransitioning=!1,this._showBackdrop((function(){t(document.body).removeClass($e),e._resetAdjustments(),e._resetScrollbar(),t(e._element).trigger(Ue.HIDDEN)}))},n._removeBackdrop=function(){this._backdrop&&(t(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(e){var n=this,r=t(this._element).hasClass(Xe)?Xe:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className=Ze,r&&this._backdrop.classList.add(r),t(this._backdrop).appendTo(document.body),t(this._element).on(Ue.CLICK_DISMISS,(function(e){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:e.target===e.currentTarget&&n._triggerBackdropTransition()})),r&&c.reflow(this._backdrop),t(this._backdrop).addClass(Ke),!e)return;if(!r)return void e();var a=c.getTransitionDurationFromElement(this._backdrop);t(this._backdrop).one(c.TRANSITION_END,e).emulateTransitionEnd(a)}else if(!this._isShown&&this._backdrop){t(this._backdrop).removeClass(Ke);var i=function(){n._removeBackdrop(),e&&e()};if(t(this._element).hasClass(Xe)){var o=c.getTransitionDurationFromElement(this._backdrop);t(this._backdrop).one(c.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}else e&&e()},n._adjustDialog=function(){var e=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var e=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(at)),r=[].slice.call(document.querySelectorAll(it));t(n).each((function(n,r){var a=r.style.paddingRight,i=t(r).css("padding-right");t(r).data("padding-right",a).css("padding-right",parseFloat(i)+e._scrollbarWidth+"px")})),t(r).each((function(n,r){var a=r.style.marginRight,i=t(r).css("margin-right");t(r).data("margin-right",a).css("margin-right",parseFloat(i)-e._scrollbarWidth+"px")}));var a=document.body.style.paddingRight,i=t(document.body).css("padding-right");t(document.body).data("padding-right",a).css("padding-right",parseFloat(i)+this._scrollbarWidth+"px")}t(document.body).addClass($e)},n._resetScrollbar=function(){var e=[].slice.call(document.querySelectorAll(at));t(e).each((function(e,n){var r=t(n).data("padding-right");t(n).removeData("padding-right"),n.style.paddingRight=r||""}));var n=[].slice.call(document.querySelectorAll(""+it));t(n).each((function(e,n){var r=t(n).data("margin-right");void 0!==r&&t(n).css("margin-right",r).removeData("margin-right")}));var r=t(document.body).data("padding-right");t(document.body).removeData("padding-right"),document.body.style.paddingRight=r||""},n._getScrollbarWidth=function(){var e=document.createElement("div");e.className=Je,document.body.appendChild(e);var t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},e._jQueryInterface=function(n,r){return this.each((function(){var a=t(this).data("bs.modal"),i=s({},qe,{},t(this).data(),{},"object"==typeof n&&n?n:{});if(a||(a=new e(this,i),t(this).data("bs.modal",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n](r)}else i.show&&a.show(r)}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return qe}}]),e}();t(document).on(Ue.CLICK_DATA_API,nt,(function(e){var n,r=this,a=c.getSelectorFromElement(this);a&&(n=document.querySelector(a));var i=t(n).data("bs.modal")?"toggle":s({},t(n).data(),{},t(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||e.preventDefault();var o=t(n).one(Ue.SHOW,(function(e){e.isDefaultPrevented()||o.one(Ue.HIDDEN,(function(){t(r).is(":visible")&&r.focus()}))}));ot._jQueryInterface.call(t(n),i,this)})),t.fn.modal=ot._jQueryInterface,t.fn.modal.Constructor=ot,t.fn.modal.noConflict=function(){return t.fn.modal=Be,ot._jQueryInterface};var st=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],lt={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},ct=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,ut=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function dt(e,t,n){if(0===e.length)return e;if(n&&"function"==typeof n)return n(e);for(var r=(new window.DOMParser).parseFromString(e,"text/html"),a=Object.keys(t),i=[].slice.call(r.body.querySelectorAll("*")),o=function(e,n){var r=i[e],o=r.nodeName.toLowerCase();if(-1===a.indexOf(r.nodeName.toLowerCase()))return r.parentNode.removeChild(r),"continue";var s=[].slice.call(r.attributes),l=[].concat(t["*"]||[],t[o]||[]);s.forEach((function(e){(function(e,t){var n=e.nodeName.toLowerCase();if(-1!==t.indexOf(n))return-1===st.indexOf(n)||Boolean(e.nodeValue.match(ct)||e.nodeValue.match(ut));for(var r=t.filter((function(e){return e instanceof RegExp})),a=0,i=r.length;a<i;a++)if(n.match(r[a]))return!0;return!1})(e,l)||r.removeAttribute(e.nodeName)}))},s=0,l=i.length;s<l;s++)o(s);return r.body.innerHTML}var ft="tooltip",ht=t.fn[ft],pt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),mt=["sanitize","whiteList","sanitizeFn"],gt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},yt={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},_t={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:lt,popperConfig:null},vt="show",xt="out",bt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Mt="fade",wt="show",kt=".tooltip-inner",Tt=".arrow",Lt="hover",Dt="focus",At="click",St="manual",Yt=function(){function e(e,t){if(void 0===n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var r=e.prototype;return r.enable=function(){this._isEnabled=!0},r.disable=function(){this._isEnabled=!1},r.toggleEnabled=function(){this._isEnabled=!this._isEnabled},r.toggle=function(e){if(this._isEnabled)if(e){var n=this.constructor.DATA_KEY,r=t(e.currentTarget).data(n);r||(r=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,r)),r._activeTrigger.click=!r._activeTrigger.click,r._isWithActiveTrigger()?r._enter(null,r):r._leave(null,r)}else{if(t(this.getTipElement()).hasClass(wt))return void this._leave(null,this);this._enter(null,this)}},r.dispose=function(){clearTimeout(this._timeout),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),t(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},r.show=function(){var e=this;if("none"===t(this.element).css("display"))throw new Error("Please use show on visible elements");var r=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){t(this.element).trigger(r);var a=c.findShadowRoot(this.element),i=t.contains(null!==a?a:this.element.ownerDocument.documentElement,this.element);if(r.isDefaultPrevented()||!i)return;var o=this.getTipElement(),s=c.getUID(this.constructor.NAME);o.setAttribute("id",s),this.element.setAttribute("aria-describedby",s),this.setContent(),this.config.animation&&t(o).addClass(Mt);var l="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,u=this._getAttachment(l);this.addAttachmentClass(u);var d=this._getContainer();t(o).data(this.constructor.DATA_KEY,this),t.contains(this.element.ownerDocument.documentElement,this.tip)||t(o).appendTo(d),t(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,o,this._getPopperConfig(u)),t(o).addClass(wt),"ontouchstart"in document.documentElement&&t(document.body).children().on("mouseover",null,t.noop);var f=function(){e.config.animation&&e._fixTransition();var n=e._hoverState;e._hoverState=null,t(e.element).trigger(e.constructor.Event.SHOWN),n===xt&&e._leave(null,e)};if(t(this.tip).hasClass(Mt)){var h=c.getTransitionDurationFromElement(this.tip);t(this.tip).one(c.TRANSITION_END,f).emulateTransitionEnd(h)}else f()}},r.hide=function(e){var n=this,r=this.getTipElement(),a=t.Event(this.constructor.Event.HIDE),i=function(){n._hoverState!==vt&&r.parentNode&&r.parentNode.removeChild(r),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()};if(t(this.element).trigger(a),!a.isDefaultPrevented()){if(t(r).removeClass(wt),"ontouchstart"in document.documentElement&&t(document.body).children().off("mouseover",null,t.noop),this._activeTrigger[At]=!1,this._activeTrigger[Dt]=!1,this._activeTrigger[Lt]=!1,t(this.tip).hasClass(Mt)){var o=c.getTransitionDurationFromElement(r);t(r).one(c.TRANSITION_END,i).emulateTransitionEnd(o)}else i();this._hoverState=""}},r.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},r.isWithContent=function(){return Boolean(this.getTitle())},r.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-tooltip-"+e)},r.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},r.setContent=function(){var e=this.getTipElement();this.setElementContent(t(e.querySelectorAll(kt)),this.getTitle()),t(e).removeClass(Mt+" "+wt)},r.setElementContent=function(e,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=dt(n,this.config.whiteList,this.config.sanitizeFn)),e.html(n)):e.text(n):this.config.html?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text())},r.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e||(e="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),e},r._getPopperConfig=function(e){var t=this;return s({},{placement:e,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Tt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}},{},this.config.popperConfig)},r._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=s({},t.offsets,{},e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},r._getContainer=function(){return!1===this.config.container?document.body:c.isElement(this.config.container)?t(this.config.container):t(document).find(this.config.container)},r._getAttachment=function(e){return yt[e.toUpperCase()]},r._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,(function(t){return e.toggle(t)}));else if(n!==St){var r=n===Lt?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,a=n===Lt?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(r,e.config.selector,(function(t){return e._enter(t)})).on(a,e.config.selector,(function(t){return e._leave(t)}))}})),this._hideModalHandler=function(){e.element&&e.hide()},t(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},r._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==e)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},r._enter=function(e,n){var r=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(r))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(r,n)),e&&(n._activeTrigger["focusin"===e.type?Dt:Lt]=!0),t(n.getTipElement()).hasClass(wt)||n._hoverState===vt?n._hoverState=vt:(clearTimeout(n._timeout),n._hoverState=vt,n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){n._hoverState===vt&&n.show()}),n.config.delay.show):n.show())},r._leave=function(e,n){var r=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(r))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(r,n)),e&&(n._activeTrigger["focusout"===e.type?Dt:Lt]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState=xt,n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){n._hoverState===xt&&n.hide()}),n.config.delay.hide):n.hide())},r._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},r._getConfig=function(e){var n=t(this.element).data();return Object.keys(n).forEach((function(e){-1!==mt.indexOf(e)&&delete n[e]})),"number"==typeof(e=s({},this.constructor.Default,{},n,{},"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),c.typeCheckConfig(ft,e,this.constructor.DefaultType),e.sanitize&&(e.template=dt(e.template,e.whiteList,e.sanitizeFn)),e},r._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},r._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(pt);null!==n&&n.length&&e.removeClass(n.join(""))},r._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},r._fixTransition=function(){var e=this.getTipElement(),n=this.config.animation;null===e.getAttribute("x-placement")&&(t(e).removeClass(Mt),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.tooltip"),a="object"==typeof n&&n;if((r||!/dispose|hide/.test(n))&&(r||(r=new e(this,a),t(this).data("bs.tooltip",r)),"string"==typeof n)){if(void 0===r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return _t}},{key:"NAME",get:function(){return ft}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return bt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return gt}}]),e}();t.fn[ft]=Yt._jQueryInterface,t.fn[ft].Constructor=Yt,t.fn[ft].noConflict=function(){return t.fn[ft]=ht,Yt._jQueryInterface};var Ct="popover",Ot=t.fn[Ct],Et=new RegExp("(^|\\s)bs-popover\\S+","g"),Pt=s({},Yt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Ht=s({},Yt.DefaultType,{content:"(string|element|function)"}),jt="fade",zt="show",It=".popover-header",Nt=".popover-body",Ft={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Rt=function(e){var n,r;function i(){return e.apply(this,arguments)||this}r=e,(n=i).prototype=Object.create(r.prototype),n.prototype.constructor=n,n.__proto__=r;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-popover-"+e)},o.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},o.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(It),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(e.find(Nt),n),e.removeClass(jt+" "+zt)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(Et);null!==n&&n.length>0&&e.removeClass(n.join(""))},i._jQueryInterface=function(e){return this.each((function(){var n=t(this).data("bs.popover"),r="object"==typeof e?e:null;if((n||!/dispose|hide/.test(e))&&(n||(n=new i(this,r),t(this).data("bs.popover",n)),"string"==typeof e)){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},a(i,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return Pt}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return Ft}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Ht}}]),i}(Yt);t.fn[Ct]=Rt._jQueryInterface,t.fn[Ct].Constructor=Rt,t.fn[Ct].noConflict=function(){return t.fn[Ct]=Ot,Rt._jQueryInterface};var Wt="scrollspy",Bt=t.fn[Wt],qt={offset:10,method:"auto",target:""},Vt={offset:"number",method:"string",target:"(string|element)"},Ut={ACTIVATE:"activate.bs.scrollspy",SCROLL:"scroll.bs.scrollspy",LOAD_DATA_API:"load.bs.scrollspy.data-api"},Gt="dropdown-item",Jt="active",Zt='[data-spy="scroll"]',$t=".nav, .list-group",Xt=".nav-link",Kt=".nav-item",Qt=".list-group-item",en=".dropdown",tn=".dropdown-item",nn=".dropdown-toggle",rn="offset",an="position",on=function(){function e(e,n){var r=this;this._element=e,this._scrollElement="BODY"===e.tagName?window:e,this._config=this._getConfig(n),this._selector=this._config.target+" "+Xt+","+this._config.target+" "+Qt+","+this._config.target+" "+tn,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,t(this._scrollElement).on(Ut.SCROLL,(function(e){return r._process(e)})),this.refresh(),this._process()}var n=e.prototype;return n.refresh=function(){var e=this,n=this._scrollElement===this._scrollElement.window?rn:an,r="auto"===this._config.method?n:this._config.method,a=r===an?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(e){var n,i=c.getSelectorFromElement(e);if(i&&(n=document.querySelector(i)),n){var o=n.getBoundingClientRect();if(o.width||o.height)return[t(n)[r]().top+a,i]}return null})).filter((function(e){return e})).sort((function(e,t){return e[0]-t[0]})).forEach((function(t){e._offsets.push(t[0]),e._targets.push(t[1])}))},n.dispose=function(){t.removeData(this._element,"bs.scrollspy"),t(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(e){if("string"!=typeof(e=s({},qt,{},"object"==typeof e&&e?e:{})).target){var n=t(e.target).attr("id");n||(n=c.getUID(Wt),t(e.target).attr("id",n)),e.target="#"+n}return c.typeCheckConfig(Wt,e,Vt),e},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var e=this._getScrollTop()+this._config.offset,t=this._getScrollHeight(),n=this._config.offset+t-this._getOffsetHeight();if(this._scrollHeight!==t&&this.refresh(),e>=n){var r=this._targets[this._targets.length-1];this._activeTarget!==r&&this._activate(r)}else{if(this._activeTarget&&e<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var a=this._offsets.length;a--;)this._activeTarget!==this._targets[a]&&e>=this._offsets[a]&&(void 0===this._offsets[a+1]||e<this._offsets[a+1])&&this._activate(this._targets[a])}},n._activate=function(e){this._activeTarget=e,this._clear();var n=this._selector.split(",").map((function(t){return t+'[data-target="'+e+'"],'+t+'[href="'+e+'"]'})),r=t([].slice.call(document.querySelectorAll(n.join(","))));r.hasClass(Gt)?(r.closest(en).find(nn).addClass(Jt),r.addClass(Jt)):(r.addClass(Jt),r.parents($t).prev(Xt+", "+Qt).addClass(Jt),r.parents($t).prev(Kt).children(Xt).addClass(Jt)),t(this._scrollElement).trigger(Ut.ACTIVATE,{relatedTarget:e})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(e){return e.classList.contains(Jt)})).forEach((function(e){return e.classList.remove(Jt)}))},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.scrollspy");if(r||(r=new e(this,"object"==typeof n&&n),t(this).data("bs.scrollspy",r)),"string"==typeof n){if(void 0===r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return qt}}]),e}();t(window).on(Ut.LOAD_DATA_API,(function(){for(var e=[].slice.call(document.querySelectorAll(Zt)),n=e.length;n--;){var r=t(e[n]);on._jQueryInterface.call(r,r.data())}})),t.fn[Wt]=on._jQueryInterface,t.fn[Wt].Constructor=on,t.fn[Wt].noConflict=function(){return t.fn[Wt]=Bt,on._jQueryInterface};var sn=t.fn.tab,ln={HIDE:"hide.bs.tab",HIDDEN:"hidden.bs.tab",SHOW:"show.bs.tab",SHOWN:"shown.bs.tab",CLICK_DATA_API:"click.bs.tab.data-api"},cn="dropdown-menu",un="active",dn="disabled",fn="fade",hn="show",pn=".dropdown",mn=".nav, .list-group",gn=".active",yn="> li > .active",_n='[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',vn=".dropdown-toggle",xn="> .dropdown-menu .active",bn=function(){function e(e){this._element=e}var n=e.prototype;return n.show=function(){var e=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&t(this._element).hasClass(un)||t(this._element).hasClass(dn))){var n,r,a=t(this._element).closest(mn)[0],i=c.getSelectorFromElement(this._element);if(a){var o="UL"===a.nodeName||"OL"===a.nodeName?yn:gn;r=(r=t.makeArray(t(a).find(o)))[r.length-1]}var s=t.Event(ln.HIDE,{relatedTarget:this._element}),l=t.Event(ln.SHOW,{relatedTarget:r});if(r&&t(r).trigger(s),t(this._element).trigger(l),!l.isDefaultPrevented()&&!s.isDefaultPrevented()){i&&(n=document.querySelector(i)),this._activate(this._element,a);var u=function(){var n=t.Event(ln.HIDDEN,{relatedTarget:e._element}),a=t.Event(ln.SHOWN,{relatedTarget:r});t(r).trigger(n),t(e._element).trigger(a)};n?this._activate(n,n.parentNode,u):u()}}},n.dispose=function(){t.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(e,n,r){var a=this,i=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?t(n).children(gn):t(n).find(yn))[0],o=r&&i&&t(i).hasClass(fn),s=function(){return a._transitionComplete(e,i,r)};if(i&&o){var l=c.getTransitionDurationFromElement(i);t(i).removeClass(hn).one(c.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},n._transitionComplete=function(e,n,r){if(n){t(n).removeClass(un);var a=t(n.parentNode).find(xn)[0];a&&t(a).removeClass(un),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(t(e).addClass(un),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!0),c.reflow(e),e.classList.contains(fn)&&e.classList.add(hn),e.parentNode&&t(e.parentNode).hasClass(cn)){var i=t(e).closest(pn)[0];if(i){var o=[].slice.call(i.querySelectorAll(vn));t(o).addClass(un)}e.setAttribute("aria-expanded",!0)}r&&r()},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.tab");if(a||(a=new e(this),r.data("bs.tab",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}}]),e}();t(document).on(ln.CLICK_DATA_API,_n,(function(e){e.preventDefault(),bn._jQueryInterface.call(t(this),"show")})),t.fn.tab=bn._jQueryInterface,t.fn.tab.Constructor=bn,t.fn.tab.noConflict=function(){return t.fn.tab=sn,bn._jQueryInterface};var Mn=t.fn.toast,wn={CLICK_DISMISS:"click.dismiss.bs.toast",HIDE:"hide.bs.toast",HIDDEN:"hidden.bs.toast",SHOW:"show.bs.toast",SHOWN:"shown.bs.toast"},kn="fade",Tn="hide",Ln="show",Dn="showing",An={animation:"boolean",autohide:"boolean",delay:"number"},Sn={animation:!0,autohide:!0,delay:500},Yn='[data-dismiss="toast"]',Cn=function(){function e(e,t){this._element=e,this._config=this._getConfig(t),this._timeout=null,this._setListeners()}var n=e.prototype;return n.show=function(){var e=this,n=t.Event(wn.SHOW);if(t(this._element).trigger(n),!n.isDefaultPrevented()){this._config.animation&&this._element.classList.add(kn);var r=function(){e._element.classList.remove(Dn),e._element.classList.add(Ln),t(e._element).trigger(wn.SHOWN),e._config.autohide&&(e._timeout=setTimeout((function(){e.hide()}),e._config.delay))};if(this._element.classList.remove(Tn),c.reflow(this._element),this._element.classList.add(Dn),this._config.animation){var a=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}},n.hide=function(){if(this._element.classList.contains(Ln)){var e=t.Event(wn.HIDE);t(this._element).trigger(e),e.isDefaultPrevented()||this._close()}},n.dispose=function(){clearTimeout(this._timeout),this._timeout=null,this._element.classList.contains(Ln)&&this._element.classList.remove(Ln),t(this._element).off(wn.CLICK_DISMISS),t.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(e){return e=s({},Sn,{},t(this._element).data(),{},"object"==typeof e&&e?e:{}),c.typeCheckConfig("toast",e,this.constructor.DefaultType),e},n._setListeners=function(){var e=this;t(this._element).on(wn.CLICK_DISMISS,Yn,(function(){return e.hide()}))},n._close=function(){var e=this,n=function(){e._element.classList.add(Tn),t(e._element).trigger(wn.HIDDEN)};if(this._element.classList.remove(Ln),this._config.animation){var r=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,n).emulateTransitionEnd(r)}else n()},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.toast");if(a||(a=new e(this,"object"==typeof n&&n),r.data("bs.toast",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n](this)}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"DefaultType",get:function(){return An}},{key:"Default",get:function(){return Sn}}]),e}();t.fn.toast=Cn._jQueryInterface,t.fn.toast.Constructor=Cn,t.fn.toast.noConflict=function(){return t.fn.toast=Mn,Cn._jQueryInterface},e.Alert=g,e.Button=S,e.Carousel=re,e.Collapse=ye,e.Dropdown=We,e.Modal=ot,e.Popover=Rt,e.Scrollspy=on,e.Tab=bn,e.Toast=Cn,e.Tooltip=Yt,e.Util=c,Object.defineProperty(e,"__esModule",{value:!0})}(t,n(1),n(3))},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){var r={"./af":4,"./af.js":4,"./ar":5,"./ar-dz":6,"./ar-dz.js":6,"./ar-kw":7,"./ar-kw.js":7,"./ar-ly":8,"./ar-ly.js":8,"./ar-ma":9,"./ar-ma.js":9,"./ar-sa":10,"./ar-sa.js":10,"./ar-tn":11,"./ar-tn.js":11,"./ar.js":5,"./az":12,"./az.js":12,"./be":13,"./be.js":13,"./bg":14,"./bg.js":14,"./bm":15,"./bm.js":15,"./bn":16,"./bn.js":16,"./bo":17,"./bo.js":17,"./br":18,"./br.js":18,"./bs":19,"./bs.js":19,"./ca":20,"./ca.js":20,"./cs":21,"./cs.js":21,"./cv":22,"./cv.js":22,"./cy":23,"./cy.js":23,"./da":24,"./da.js":24,"./de":25,"./de-at":26,"./de-at.js":26,"./de-ch":27,"./de-ch.js":27,"./de.js":25,"./dv":28,"./dv.js":28,"./el":29,"./el.js":29,"./en-SG":30,"./en-SG.js":30,"./en-au":31,"./en-au.js":31,"./en-ca":32,"./en-ca.js":32,"./en-gb":33,"./en-gb.js":33,"./en-ie":34,"./en-ie.js":34,"./en-il":35,"./en-il.js":35,"./en-nz":36,"./en-nz.js":36,"./eo":37,"./eo.js":37,"./es":38,"./es-do":39,"./es-do.js":39,"./es-us":40,"./es-us.js":40,"./es.js":38,"./et":41,"./et.js":41,"./eu":42,"./eu.js":42,"./fa":43,"./fa.js":43,"./fi":44,"./fi.js":44,"./fo":45,"./fo.js":45,"./fr":46,"./fr-ca":47,"./fr-ca.js":47,"./fr-ch":48,"./fr-ch.js":48,"./fr.js":46,"./fy":49,"./fy.js":49,"./ga":50,"./ga.js":50,"./gd":51,"./gd.js":51,"./gl":52,"./gl.js":52,"./gom-latn":53,"./gom-latn.js":53,"./gu":54,"./gu.js":54,"./he":55,"./he.js":55,"./hi":56,"./hi.js":56,"./hr":57,"./hr.js":57,"./hu":58,"./hu.js":58,"./hy-am":59,"./hy-am.js":59,"./id":60,"./id.js":60,"./is":61,"./is.js":61,"./it":62,"./it-ch":63,"./it-ch.js":63,"./it.js":62,"./ja":64,"./ja.js":64,"./jv":65,"./jv.js":65,"./ka":66,"./ka.js":66,"./kk":67,"./kk.js":67,"./km":68,"./km.js":68,"./kn":69,"./kn.js":69,"./ko":70,"./ko.js":70,"./ku":71,"./ku.js":71,"./ky":72,"./ky.js":72,"./lb":73,"./lb.js":73,"./lo":74,"./lo.js":74,"./lt":75,"./lt.js":75,"./lv":76,"./lv.js":76,"./me":77,"./me.js":77,"./mi":78,"./mi.js":78,"./mk":79,"./mk.js":79,"./ml":80,"./ml.js":80,"./mn":81,"./mn.js":81,"./mr":82,"./mr.js":82,"./ms":83,"./ms-my":84,"./ms-my.js":84,"./ms.js":83,"./mt":85,"./mt.js":85,"./my":86,"./my.js":86,"./nb":87,"./nb.js":87,"./ne":88,"./ne.js":88,"./nl":89,"./nl-be":90,"./nl-be.js":90,"./nl.js":89,"./nn":91,"./nn.js":91,"./pa-in":92,"./pa-in.js":92,"./pl":93,"./pl.js":93,"./pt":94,"./pt-br":95,"./pt-br.js":95,"./pt.js":94,"./ro":96,"./ro.js":96,"./ru":97,"./ru.js":97,"./sd":98,"./sd.js":98,"./se":99,"./se.js":99,"./si":100,"./si.js":100,"./sk":101,"./sk.js":101,"./sl":102,"./sl.js":102,"./sq":103,"./sq.js":103,"./sr":104,"./sr-cyrl":105,"./sr-cyrl.js":105,"./sr.js":104,"./ss":106,"./ss.js":106,"./sv":107,"./sv.js":107,"./sw":108,"./sw.js":108,"./ta":109,"./ta.js":109,"./te":110,"./te.js":110,"./tet":111,"./tet.js":111,"./tg":112,"./tg.js":112,"./th":113,"./th.js":113,"./tl-ph":114,"./tl-ph.js":114,"./tlh":115,"./tlh.js":115,"./tr":116,"./tr.js":116,"./tzl":117,"./tzl.js":117,"./tzm":118,"./tzm-latn":119,"./tzm-latn.js":119,"./tzm.js":118,"./ug-cn":120,"./ug-cn.js":120,"./uk":121,"./uk.js":121,"./ur":122,"./ur.js":122,"./uz":123,"./uz-latn":124,"./uz-latn.js":124,"./uz.js":123,"./vi":125,"./vi.js":125,"./x-pseudo":126,"./x-pseudo.js":126,"./yo":127,"./yo.js":127,"./zh-cn":128,"./zh-cn.js":128,"./zh-hk":129,"./zh-hk.js":129,"./zh-tw":130,"./zh-tw.js":130};function a(e){var t=i(e);return n(t)}function i(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=i,e.exports=a,a.id=135},function(e,t,n){"use strict";n.r(t),t.default=n.p+"css/app.css"},function(e,t,n){"use strict";n.r(t);n.p;var r=n(131),a=n.n(r),i=n(1),o=n.n(i),s=n(0),l=n.n(s);function c(e,t,n,r,a){function i(t){const n=Number(t)*e.pageSize,r=(Number(t)+1)*Number(e.pageSize);return e.table.filter(t=>t.name.includes(e.searchQuery)).slice(n,r)}a.reset(),r.reset("overview"),e.alertShow=!1,e.pypi_version="",e.dashboard_version="",e.isHits=!0,e.table=[],e.selectedItem=2,e.searchQuery="",e.pageSize="10",e.currentPage=0,e.toggleHits=function(){e.isHits=!e.isHits},t.get("api/overview").then((function(t){e.table=t.data})),e.getFilteredItems=function(){return i(e.currentPage)},e.canGoBack=function(){return e.currentPage>0},e.canGoForward=function(){return i(e.currentPage+1).length>0},e.nextPage=function(){e.currentPage++},e.previousPage=function(){e.currentPage--},e.go=function(e){n.path(e)},t.get("https://pypi.org/pypi/Flask-MonitoringDashboard/json").then((function(n){e.pypi_version=n.data.info.version,t.get("api/deploy_details").then((function(t){e.dashboard_version=t.data["dashboard-version"],e.alertShow=!function(e,t){let n=e.split("."),r=t.split(".");for(let e=0;e<3;e++){if(n[e]>r[e])return!1;if(n[e]<r[e])return!0}return!0}(e.pypi_version,e.dashboard_version)}))}))}function u(e,t,n,r,a,i,o,s){o.reset(),n.reset("hourly_load"),e.title="Hourly API Utilization",a.axesText="The X-axis represents the dates. The Y-axis presents the hours of the day.",a.contentText="The cell color represents the number of requests that the application received in a single hour. The darker the cell, the more requests it has processed. This information can be used to to discover the peak usage hours of the Flask application.",i.clear();let l=i.addDate("Start date");i.addDate("End date"),l.value.setDate(l.value.getDate()-14),i.setReload((function(){let e=i.getDate("Start date"),n=i.getDate("End date"),a=[...Array(24).keys()].map(e=>e+":00");t.get("api/hourly_load/"+e+"/"+n).then((function(e){let t=e.data.days,n=a,i=e.data.data,o=i.map((e,n)=>e.map((e,r)=>`Date: ${s("dateShort")(t[r])}<br>Time: ${n+":00"}<br>Requests: ${e}`));r.heatmap(t,n,i,{yaxis:{autorange:"reversed"},margin:{l:50}},o)}))})),i.reload()}function d(e,t,n,r,a,i,o){o.reset(),n.reset("multi_version"),e.title="Multi version API Utilization",a.axesText="The X-axis presents the versions that are used. The Y-axis presents theendpoints that are found in the Flask application.",a.contentText="The color of the cell presents the distribution of the amount of requests that the application received in a single version for a single endpoint. The darker the cell, the more requests a certain endpoint has processed in that version. Since it displays the distribution of the load, each column sums up to 100%. This information can be used to discover which endpoints process the most requests.",r.clear(),r.addVersions(),r.addEndpoints(),r.setReload((function(){let e=r.getMultiSelection("versions"),n=r.getMultiSelection("endpoints");t.post("api/multi_version",{data:{versions:e,endpoints:n}}).then((function(t){i.heatmap(e,n,t.data.map(e=>e.map(e=>0==e?"NaN":e)),{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category"}})}))}))}function f(e,t,n,r,a,i,o){o.reset(),n.reset("daily_load"),e.title="Daily API Utilization",a.axesText="The X-axis presents the amount of requests. The Y-axis presents a number of days.",a.contentText="This graph presents a horizontal stacked barplot. Each endpoint is represented by a color. In the legend on the right, you can disable a certain endpoint by clicking on it. You can also show in the information of a single endpoint by double clicking that endpoint in the legend. The information from this graph can be used to see on which days (a subset of) the endpoints are used the most.",r.clear();let s=r.addDate("Start date");s.value.setDate(s.value.getDate()-10),r.addDate("End date"),r.setReload((function(){let e=r.getDate("Start date"),n=r.getDate("End date");t.get("api/requests/"+e+"/"+n).then((function(e){let t=e.data.data.map(t=>({x:t.values,y:e.data.days,name:t.name,type:"bar",orientation:"h"}));i.chart(t,{barmode:"stack",xaxis:{title:"Number of requests"},yaxis:{type:"category",autorange:"reversed"}})}))})),r.reload()}function h(e,t,n,r,a,i,o){o.reset(),n.reset("api_performance"),e.title="API Performance",a.axesText="The X-axis presents the execution time in ms. The Y-axis presents every endpoint of the Flask application.",a.contentText="In this graph, it is easy to compare the execution times of different endpoints. This information can be used to discover which endpoints need to be improved in terms of response times.",r.clear(),r.addEndpoints(),r.setReload((function(){t.post("api/api_performance",{data:{endpoints:r.getMultiSelection("endpoints")}}).then((function(e){let t=e.data.map(e=>({x:e.values,type:"box",name:e.name}));i.chart(t,{xaxis:{title:"Execution time (ms)"},yaxis:{type:"category"}})}))}))}function p(e,t,n,r,a){function i(e,t){const n=moment().subtract(e,t).startOf(t),r=moment().subtract(e,t).endOf(t),a=moment().startOf(t),i=moment().endOf(t);return{comparison:{from:a.toDate(),to:i.toDate()},baseline:{from:n.toDate(),to:r.toDate()}}}r.reset(),n.reset("reporting"),e.reports={},e.activeSection="week",e.monthName=moment().format("MMMM"),e.previousMonthName=moment().subtract(1,"months").format("MMMM"),e.currentDay=moment().format("MMM DD"),e.yesterday=moment().subtract(1,"days").format("MMM DD"),e.currentWeekNumber=moment().isoWeek(),e.previousWeekNumber=moment().subtract(1,"weeks").isoWeek(),e.generating=!1,e.onlyShowInteresting=!0,e.activeSection="custom",e.intervals=i(1,"months"),e.versions=[],e.commitVersion=null,e.baseLineCommitVersion=null,e.selectSection=function(n){"commits"===n&&t.get("/dashboard/api/versions").then((function(t){e.versions=t.data})),e.activeSection=n;const r={day:[1,"days"],week:[1,"isoWeeks"],month:[1,"months"],custom:[1,"isoWeeks"]}[e.activeSection];e.intervals=i(r[0],r[1])},e.selectEntry=function(t,n){e.selectedSummary=t,e.selectedAnswer=n;const{comparison:r,baseline:i}=n.latencies_samples,o=[{name:`Comparison (N=${r.length})`,type:"violin",y:r},{name:`Baseline (N=${i.length})`,type:"violin",y:i}];a.chart(o,{yaxis:{title:"Execution time (ms)",rangemode:"nonnegative"}})},e.generateReport=function(){let n;e.generating=!0,e.error="",n="commits"===e.activeSection?t.post("/dashboard/api/reporting/make_report/commits",{commit_version:e.commitVersion,baseline_commit_version:e.baseLineCommitVersion}):t.post("/dashboard/api/reporting/make_report/intervals",{interval:{to:parseInt(""+e.intervals.comparison.to.getTime()/1e3),from:parseInt(""+e.intervals.comparison.from.getTime()/1e3)},baseline_interval:{to:parseInt(""+e.intervals.baseline.to.getTime()/1e3),from:parseInt(""+e.intervals.baseline.from.getTime()/1e3)}}),n.then(t=>{e.reports[e.activeSection]=t.data,e.generating=!1}),n.catch(t=>{e.error=t.data.message||"An unknown error occurred!",e.generating=!1})}}function m(e,t,n,r,a,i,o,s){r.reset(),n.reset("endpoint_hourly"),r.onNameChanged=function(t){e.title="Hourly API Utilization for "+t},a.axesText="The X-axis represents the dates. The Y-axis presents the hours of the day.",a.contentText="The cell color represents the number of requests that the application received in a single hour for this endpoint. The darker the cell, the more requests it has processed. This information can be used to discover the peak usage hours of this endpoint.",i.clear();let l=i.addDate("Start date");i.addDate("End date"),l.value.setDate(l.value.getDate()-14),i.setReload((function(){let e=i.getDate("Start date"),n=i.getDate("End date"),a=[...Array(24).keys()].map(e=>e+":00 ");t.get("api/hourly_load/"+e+"/"+n+"/"+r.info.id).then((function(e){let t=e.data.days,n=a,r=e.data.data,i=r.map((e,n)=>e.map((e,r)=>`Date: ${s("dateShort")(t[r])}<br>Time: ${n+":00"}<br>Requests: ${e}`));o.heatmap(t,n,r,{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category",autorange:"reversed"},margin:{l:50}},i)}))})),i.reload()}function g(e,t,n,r,a,i,o,s){r.reset(),a.reset("endpoint_user_version"),r.onNameChanged=function(t){e.title="User-Focused Multi-Version Performance for "+t},n.axesText='In this graph, the X-axis presents the versions that are used. The Y-axis presents (a subset of) all unique users, as specified by "dashboard.config.group_by". You can use the slider to select a subset of the all unique users.',n.contentText="The cell color represents the average response time (expressed in ms) of this endpoint per user per version.",i.clear(),i.addUsers(),i.addVersions(r.info.id),i.setReload((function(){t.post("api/version_user/"+r.info.id,{data:{versions:i.getMultiSelection("versions"),users:i.getMultiSelection("users")}}).then((function(e){let t=e.data.versions.map(e=>e.version+"<br>"+s("dateLayout")(e.date));o.heatmap(t,i.getMultiSelection("users"),e.data.data,{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category",title:"Users",autorange:"reversed"}})}))}))}function y(e,t,n,r,a,i,o){r.reset(),a.reset("endpoint_user"),r.onNameChanged=function(t){e.title="Per-User Performance for "+t},n.axesText="The X-axis presents the execution time in ms. The Y-axis presents the versions that are used.",n.contentText="This graph shows a horizontal boxplot for the versions that are used. With this graph you can found out whether the performance changes across different versions.",i.clear(),i.addUsers(),i.setReload((function(){t.post("api/endpoint_users/"+r.info.id,{data:{users:i.getMultiSelection("users")}}).then((function(e){o.chart(e.data.map(e=>({x:e.values,type:"box",name:e.user,marker:{color:e.color}})),{xaxis:{title:"Execution time (ms)"},yaxis:{type:"category",autorange:"reversed"},margin:{l:200}})}))}))}function _(e,t,n,r,a,i){r.reset(),r.onNameChanged=function(t){e.title="Profiler for "+t},n.reset("endpoint_profiler"),a.init("requests"),t.get("api/num_profiled/"+r.info.id).then((function(e){a.setTotal(e.data)})),a.onReload=function(){i.isLoading=!0,t.get("api/profiler_table/"+r.info.id+"/"+a.getLeft()+"/"+a.perPage).then((function(t){e.table=t.data,i.isLoading=!1;for(let t of e.table){let e=t.stack_lines;for(let t of e)t.min=0===parseInt(t.indent),t.showRow=parseInt(t.indent)<2,t.body=o(e,parseInt(t.position))}}))},e.buttonText=function(e){return e.stack_lines.every(e=>e.showRow)?"Hide all":"Expand all"},e.toggleButton=function(e){if(e.stack_lines.every(e=>e.showRow))for(let t of e.stack_lines)t.min=0===parseInt(t.indent),t.showRow=parseInt(t.indent)<2;else for(let t of e.stack_lines)t.showRow=!0,t.min=!0},e.toggleRows=function(e,t){if(t.min)for(let n of t.body)e.stack_lines[n].min=!1,e.stack_lines[n].showRow=!1;else for(let n of t.body)e.stack_lines[n].showRow=parseInt(e.stack_lines[n].indent)===parseInt(t.indent)+1;t.min=!t.min};let o=function(e,t){let n=[],r=t+1;for(;r<e.length&&parseInt(e[r].indent)>parseInt(e[t].indent);)n.push(r),r+=1;return n};e.computeColor=function(e){let t=[230,74,54],n=[198,220,0];return"rgb("+(t[0]*e+n[0]*(1-e))+", "+(t[1]*e+n[1]*(1-e))+", "+(t[2]*e+n[2]*(1-e))+")"}}function v(e,t,n,r,a){r.reset(),e.table=[],r.onNameChanged=function(t){e.title="Grouped profiler for "+t},n.reset("endpoint_grouped_profiler"),t.get("api/grouped_profiler/"+r.info.id).then((function(t){a.isLoading=!1,e.table=t.data;for(let t=0;t<e.table.length;t++){let n=e.table[t];n.min=0===parseInt(n.indent),n.showRow=parseInt(n.indent)<2,n.body=o(e.table,t)}let n=i(e.table,0);const r=d3.scaleOrdinal(d3.schemeCategory20);Sunburst().data(n).label("name").size("size").color((e,t)=>r(t?t.data.name:null)).tooltipContent((e,t)=>"Size: <i>"+t.value+"</i>")(document.getElementById("sunburst"))}));let i=function(t,n){if(0===n){let n=0;for(;n+1<t.length&&0===parseInt(t[n+1].indent);)n++;return{name:t[n].code,children:i(t[n].body.map(t=>e.table[t]),1)}}{let r=[];for(let a of t)parseInt(a.indent)===n&&(a.body.length>0?r.push({name:a.code,children:i(a.body.map(t=>e.table[t]),n+1)}):r.push({name:a.code,size:Math.max(a.duration,1)}));return r}};e.buttonText=function(){return e.table.every(e=>e.showRow)?"Hide all":"Expand all"},e.toggleButton=function(){if(e.table.every(e=>e.showRow))for(let t of e.table)t.min=0===parseInt(t.indent),t.showRow=parseInt(t.indent)<2;else for(let t of e.table)t.showRow=!0,t.min=!0},e.toggleRows=function(t){if(t.min)for(let n of t.body)e.table[n].min=!1,e.table[n].showRow=!1;else for(let n of t.body)e.table[n].showRow=parseInt(e.table[n].indent)===parseInt(t.indent)+1;t.min=!t.min};let o=function(e,t){let n=[],r=t+1;for(;r<e.length&&parseInt(e[r].indent)>parseInt(e[t].indent);)n.push(r),r+=1;return n};e.computeColor=function(e){let t=[230,74,54],n=[198,220,0];return"rgb("+(t[0]*e+n[0]*(1-e))+", "+(t[1]*e+n[1]*(1-e))+", "+(t[2]*e+n[2]*(1-e))+")"}}function x(e,t,n,r,a,i){e.table=[],n.reset(),r.reset("endpoint_outlier"),n.onNameChanged=function(t){e.title="Outliers for "+t},a.init("outliers"),t.get("api/num_outliers/"+n.info.id).then((function(e){a.setTotal(e.data)})),a.onReload=function(){t.get("api/outlier_table/"+n.info.id+"/"+a.getLeft()+"/"+a.perPage).then((function(t){e.table=t.data}))},t.get("api/outlier_graph/"+n.info.id).then((function(e){i.chart(e.data.map(e=>({x:e.values,type:"box",name:e.name,marker:{color:e.color}})),{xaxis:{title:"CPU loads (%)"},yaxis:{type:"category",autorange:"reversed"}})}))}function b(e,t,n,r,a,i,o){a.reset("status_code_distribution"),r.reset(),i.setReload((function(){const n=r.info.id;t.get("api/endpoint_status_code_summary/"+n).then((function(t){const n=t.data.distribution,r=Object.keys(n),a=[{values:r.map(e=>n[e]),labels:r,type:"pie"}];e.error_requests=t.data.error_requests,o.chart(a,{height:400,width:500})}))})),i.reload()}function M(e,t,n,r,a,i,o){r.reset(),a.reset("custom_graph"+r.graphId),e.title=r.getGraphTitle(),r.onNameChanged=function(t){e.title=t},n.axesText="",n.contentText="",i.clear();let s=i.addDate("Start date");s.value.setDate(s.value.getDate()-14),i.addDate("End date"),i.setReload((function(){let n=i.getDate("Start date"),a=i.getDate("End date");t.get("api/custom_graph/"+r.graphId+"/"+n+"/"+a).then((function(t){let n=t.data.map(e=>e.value),r=t.data.map(e=>e.time);o.chart([{x:r,y:n,type:"bar",name:e.title}],{yaxis:{title:"Values"},margin:{l:100}})}))})),i.reload()}const w={headers:{"Content-Type":"application/x-www-form-urlencoded;charset=utf-8;"}};function k(e,t,n,r,a){function i(){t.get("api/users").then((function(t){e.userData=t.data}))}r.reset(),n.reset("configuration"),a.setConfirm("delete",()=>{return n=e.user,void t.post("api/user/delete",$.param({user_id:n.id}),w).then((function(e){i(),$("#deleteModal").modal("hide"),a.setErrorMessage("delete",null)}),(function(e){a.setErrorMessage("delete",e.data.message)}));var n}),a.setConfirm("edit",()=>(e.user,void t.post("api/user/edit",$.param({user_id:e.user.id,old_password:$("#edit-old-pwd")[0].value,new_password:$("#edit-new-pwd")[0].value,new_password2:$("#edit-new-pwd2")[0].value,is_admin:$("#edit-admin")[0].checked}),w).then((function(e){i(),$("#editModal").modal("hide"),a.setErrorMessage("edit",null)}),(function(e){a.setErrorMessage("edit",e.data.message)})))),a.setConfirm("create",(function(){t.post("api/user/create",$.param({username:$("#create-username")[0].value,password:$("#create-pwd")[0].value,password2:$("#create-pwd2")[0].value,is_admin:$("#create-admin")[0].checked}),w).then((function(e){i(),$("#createModal").modal("hide"),a.setErrorMessage("create",null)}),(function(e){a.setErrorMessage("create",e.data.message)}))})),e.details={},e.config={},e.error={},e.userData=[],t.get("api/users").then((function(t){e.userData=t.data})),t.get("api/deploy_details").then((function(t){e.details=t.data})),t.get("api/deploy_config").then((function(t){e.config=t.data})),e.openModal=function(t,n){e.user=n,$(`#${t}Modal`).modal()}}function T(e,t,n,r,a,i,o,s){r.reset(),a.reset("endpoint_ip"),r.onNameChanged=function(t){e.title="IP-Focused Multi-Version Performance for "+t},n.axesText="In this graph, the X-axis presents the versions that are used. The Y-axis presents (a subset of) all IP-addresses. You can use the slider to select a subset of the all IP-addresses.",n.contentText="The cell color represents the average response time (expressed in ms) of this endpoint per IP per version.",i.clear(),i.addIP(),i.addVersions(r.info.id),i.setReload((function(){t.post("api/version_ip/"+r.info.id,{data:{versions:i.getMultiSelection("versions"),ip:i.getMultiSelection("IP-addresses")}}).then((function(e){let t=e.data.versions.map(e=>e.version+"<br>"+s("dateLayout")(e.date));o.heatmap(t,i.getMultiSelection("IP-addresses"),e.data.data,{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category",title:"IP-addresses"}})}))}))}function L(e,t,n,r,a,i,o,s){r.reset(),a.reset("endpoint_version"),r.onNameChanged=function(t){e.title="Per-Version Performance for "+t},n.axesText="The X-axis presents the execution time in ms. The Y-axis presents the versions that are used.",n.contentText="This graph shows a horizontal boxplot for the versions that are used. With this graph you can found out whether the performance changes across different versions.",i.clear(),i.addVersions(r.info.id),i.setReload((function(){t.post("api/endpoint_versions/"+r.info.id,{data:{versions:i.getMultiSelection("versions")}}).then((function(e){o.chart(e.data.map(e=>({x:e.values,type:"box",name:e.version+"<br>"+s("dateLayout")(e.date),marker:{color:e.color}})),{xaxis:{title:"Execution time (ms)"},yaxis:{type:"category",autorange:"reversed"},margin:{l:200}})}))}))}var D=function(e,t){this.page="",this.endpoint=t,this.reset=function(e){this.page!==e&&(this.page=e),"custom_graph"===e.substr(0,"custom_graph".length)?$("#collapseCustomGraphs").collapse("show"):$("#collapseCustomGraphs").collapse("hide");["overview","hourly_load","multi_version","daily_load","api_performance","reporting"].includes(e)?$("#collapseDashboard").collapse("show"):$("#collapseDashboard").collapse("hide");["endpoint_hourly","endpoint_user_version","endpoint_ip","endpoint_version","endpoint_user","endpoint_profiler","endpoint_grouped_profiler","endpoint_outlier","status_code_distribution"].includes(e)?$("#collapseEndpoint").collapse("show"):$("#collapseEndpoint").collapse("hide")}};window.Plotly=a.a,window.$=window.jQuery=o.a,n(133),window.moment=l.a;let A=angular.module("fmdApp",["ngRoute"]);!function(e){e.filter("duration_ms",(function(){return function(e){return Math.round(10*parseFloat(e))/10}})),e.filter("duration",(function(){return function(e){let t=Math.round(10*parseFloat(e))/10,n=t/1e3,r=Math.floor(n/60),a=Math.floor(n/3600),i=Math.floor(a/24),o="";return t<100.5?o=t+" ms":t<999.5?o=Math.round(t)+" ms":n<60?(n=Math.round(t/100)/10,o=n+" sec"):0===a?(n=Math.round(n%60),o=r+" min",n>0&&(o+=", "+n+" sec")):0===i?(o=a+" hr",r=Math.round(r%60),r>0&&(o+=", "+r+" min")):(o=i+" d",a=Math.round(a%24),a>0&&(o+=", "+a+" hr")),o}})),e.filter("dateLayout",(function(){return e=>{let t=new Date(e);return("0"+t.getDate()).slice(-2)+"-"+("0"+(t.getMonth()+1)).slice(-2)+"-"+t.getFullYear()+" "+("0"+t.getHours()).slice(-2)+":"+("0"+t.getMinutes()).slice(-2)}})),e.filter("dateShort",(function(){return e=>{let t=new Date(e),n=t.getDate(),r=t.getMonth(),a=t.getFullYear();return["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][r]+" "+n+", "+a}})),e.filter("dateDifference",(function(){return function(e){if(null===e)return"";let t=(new Date).getTime()-Date.parse(e),n=Math.round(t/1e3),r=Math.round(n/60),a=Math.round(r/60),i=Math.round(a/24),o=Math.round(i/7),s=Math.round(i/30),l=Math.round(i/365);function c(e){return 1!==e?"s":""}return n<60?n+" second"+c(n)+" ago":r<60?r+" minute"+c(r)+" ago":a<24?a+" hour"+c(a)+" ago":i<7?i+" day"+c(i)+" ago":o<5?o+" week"+c(o)+" ago":s<12?s+" month"+c(s)+" ago":l+" year"+c(l)+" ago"}})),e.filter("abs",(function(){return function(e){return Math.abs(e)}}))}(A),function(e){e.directive("pagination",(function(){return{templateUrl:"static/elements/pagination.html",controller:"PaginationController"}})),e.directive("menu",(function(){return{templateUrl:"static/elements/menu.html",controller:"MenuController"}})),e.directive("monitorlevel",(function(){return{templateUrl:"static/elements/monitorLevel.html",controller:"MonitorLevelController",scope:{name:"=",value:"="}}})),e.directive("endpointdetails",(function(){return{templateUrl:"static/elements/endpointDetails.html",controller:"EndpointController"}})),e.directive("modal",(function(){return{transclude:!0,templateUrl:"static/elements/modal.html",controller:"ModalController",scope:{name:"=",title:"=",yes:"=?",no:"=?"}}}))}(A),A.service("formService",["$http","endpointService","$filter",function(e,t,n){let r=this;function a(e){let t={name:e,values:[],selected:[],initialized:!1};return r.multiFields.push(t),t}this.dateFields=[],this.multiFields=[],this.isLoading=!0,this.clear=function(){r.multiFields=[],r.dateFields=[]},this.initialize=function(e){e.initialized=!0,r.multiFields.every(e=>e.initialized)&&r.reload()},this.getMultiSelection=function(e){return r.multiFields.find(t=>t.name==e).selected.map(e=>e.id)},this.addDate=function(e){let t={name:e,value:new Date};return r.dateFields.push(t),t},this.getDate=function(e){return i(r.dateFields.find(t=>t.name==e).value)},this.addVersions=function(t){let i=a("versions"),o="api/versions";void 0!==t&&(o+="/"+t),e.get(o).then((function(e){i.values=e.data.map(e=>({id:e.version,text:e.version+" : "+n("dateLayout")(e.date)})),i.selected=i.values.slice(-10),r.initialize(i)}))},this.addEndpoints=function(){let t=a("endpoints");e.get("api/endpoints_hits").then((function(e){t.values=e.data.map(e=>({id:e.name,text:e.name+" : "+e.hits+" requests"})),t.selected=t.values.slice(0,10),r.initialize(t)}))},this.addUsers=function(){let n=a("users");e.get("api/users/"+t.info.id).then((function(e){n.values=e.data.map(e=>({id:e.user,text:e.user+" : "+e.hits+" requests"})),n.selected=n.values.slice(0,10),r.initialize(n)}))},this.addIP=function(){let n=a("IP-addresses");e.get("api/ip/"+t.info.id).then((function(e){n.values=e.data.map(e=>({id:e.ip,text:e.ip+" : "+e.hits+" requests"})),n.selected=n.values.slice(0,10),r.initialize(n)}))};let i=function(e){return e.getFullYear()+"-"+("0"+(e.getMonth()+1)).slice(-2)+"-"+("0"+e.getDate()).slice(-2)};this.reload=function(){},this.setReload=function(e){this.reload=function(){r.isLoading=!0,e()}}}]),A.service("infoService",(function(){this.graphText="You can hover the graph with your mouse to see the actual values. You can also use the buttons at the top of the graph to select a subset of graph, scale it accordingly, or save the graph as a PNG image.",this.axesText="",this.contentText=""})),A.service("endpointService",["$http","$routeParams",function(e,t){let n=this;this.info={id:0,endpoint:""},this.graphId=0,this.customGraphs=[],this.getGraph=function(){return this.customGraphs.find(e=>e.graph_id===n.graphId)},this.getGraphTitle=function(){let e=this.getGraph();return void 0!==e?e.title:""},e.get("api/custom_graphs").then((function(e){n.customGraphs=e.data,0!==n.graphId&&n.onNameChanged(n.getGraphTitle())})),this.reset=function(){void 0!==t.endpointId?(this.info.id=t.endpointId,this.getInfo()):void 0!==t.graphId?this.graphId=t.graphId:this.info.id=0},this.onNameChanged=function(e){},this.getInfo=function(){e.get("api/endpoint_info/"+this.info.id).then((function(e){n.info=e.data,n.onNameChanged(n.info.endpoint)}))}}]),A.service("menuService",["$http","endpointService",D]),A.service("paginationService",["$http","endpointService",D]),A.service("paginationService",(function(){this.init=function(e){this.page=1,this.perPage=5,this.total=0,this.name=e},this.maxPages=function(){return Math.ceil(this.total/this.perPage)},this.onReload=function(){},this.getLeft=function(){return(this.page-1)*this.perPage},this.getRight=function(){return Math.min(this.total,this.getLeft()+this.perPage)},this.getFirstPage=function(){let e=this.getPages();return e.length>0?e[0]:this.page},this.getLastPage=function(){let e=this.getPages();return e.length>0?e[e.length-1]:this.page},this.goto=function(e){this.page=e,this.onReload()},this.setTotal=function(e){this.total=e,this.onReload()},this.getPages=function(){let e=this.page-1,t=this.page+1,n=[];e<=0&&(t-=e-1,e=1),t>this.maxPages()&&(t=this.maxPages()),2==e?n.push(1):3==e?n.push(1,2):e>3&&n.push(1,"...");for(let r=e;r<=t;r++)n.push(r);return this.maxPages()-t>2?n.push("...",this.maxPages()):this.maxPages()-t==2?n.push(this.maxPages()-1,this.maxPages()):this.maxPages()-t==1&&n.push(this.maxPages()),n}})),A.service("plotlyService",["formService",function(e){let t={height:600,margin:{l:200}},n={displaylogo:!1,responsive:!0};this.heatmap=function(e,n,r,a,i){this.chart([{x:e,y:n,z:r.map(e=>e.map(e=>0===e?NaN:e)),colorscale:"YIOrRd",reversescale:!0,type:"heatmap",text:i,hoverinfo:void 0===i?void 0:"text"}],$.extend({},t,a))},this.chart=function(r,a){e.isLoading=!1,Plotly.newPlot("chart",r,$.extend({},t,a),n)}}]),A.service("modalService",(function(){this.action={},this.error={},this.setConfirm=function(e,t){this.action[e]=t},this.setErrorMessage=function(e,t){this.error[e]=t},this.confirm=function(e){this.action[e]()}})),A.controller("MonitorLevelController",["$scope","$http",function(e,t){e.sendForm=function(n){e.value=n,t.post("api/set_rule",$.param({name:e.name,value:n}),{headers:{"Content-Type":"application/x-www-form-urlencoded;charset=utf-8;"}})},e.computeColor=function(t){let n=.2;e.value===t&&(n=1);let r=[230,74,54],a=[237,255,77],i=t/3;return"rgba("+(r[0]*i+a[0]*(1-i))+", "+(r[1]*i+a[1]*(1-i))+", "+(r[2]*i+a[2]*(1-i))+", "+n+")"}}]),A.controller("MenuController",["$scope","menuService",function(e,t){e.menu=t}]),A.controller("InfoController",["$scope","infoService",function(e,t){e.info=t}]),A.controller("FormController",["$scope","formService",function(e,t){e.handler=t}]),A.controller("EndpointController",["$scope","endpointService",function(e,t){e.endpoint=t}]),A.controller("PaginationController",["$scope","paginationService",function(e,t){e.pagination=t}]),A.controller("ModalController",["$scope","$window","$browser","modalService",function(e,t,n,r){r.setConfirm("logout",(function(){t.location.href=n.baseHref()+"logout"})),e.modal=r}]),A.config(["$locationProvider","$routeProvider",function(e,t){t.when("/overview",{templateUrl:"static/pages/overview.html",controller:["$scope","$http","$location","menuService","endpointService",c]}).when("/hourly_load",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","plotlyService","infoService","formService","endpointService","$filter",u]}).when("/multi_version",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","formService","infoService","plotlyService","endpointService",d]}).when("/daily_utilization",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","formService","infoService","plotlyService","endpointService",f]}).when("/api_performance",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","formService","infoService","plotlyService","endpointService",h]}).when("/reporting",{templateUrl:"static/pages/reporting.html",controller:["$scope","$http","menuService","endpointService","plotlyService",p]}).when("/endpoint/:endpointId/hourly_load",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","endpointService","infoService","formService","plotlyService","$filter",m]}).when("/endpoint/:endpointId/version_user",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService","$filter",g]}).when("/endpoint/:endpointId/version_ip",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService","$filter",T]}).when("/endpoint/:endpointId/versions",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService","$filter",L]}).when("/endpoint/:endpointId/users",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService",y]}).when("/endpoint/:endpointId/profiler",{templateUrl:"static/pages/profiler.html",controller:["$scope","$http","menuService","endpointService","paginationService","formService",_]}).when("/endpoint/:endpointId/grouped-profiler",{templateUrl:"static/pages/grouped_profiler.html",controller:["$scope","$http","menuService","endpointService","formService",v]}).when("/endpoint/:endpointId/outliers",{templateUrl:"static/pages/outliers.html",controller:["$scope","$http","endpointService","menuService","paginationService","plotlyService",x]}).when("/endpoint/:endpointId/status_code_distribution",{templateUrl:"static/pages/status_code_distribution.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService",b]}).when("/custom_graph/:graphId",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService",M]}).when("/configuration",{templateUrl:"static/pages/configuration.html",controller:["$scope","$http","menuService","endpointService","modalService",k]}).otherwise({redirectTo:"/overview"}),e.html5Mode({enabled:!0,requireBase:!0})}]),o()("#sidenavToggler").click((function(e){e.preventDefault(),o()("body").toggleClass("sidenav-toggled"),o()(".navbar-sidenav .nav-link-collapse").addClass("collapsed"),o()(".navbar-sidenav .sidenav-second-level, .navbar-sidenav .sidenav-third-level").removeClass("show")})),o()(".navbar-sidenav .nav-link-collapse").click((function(e){e.preventDefault(),o()("body").removeClass("sidenav-toggled")})),window.app=A}]);
\ No newline at end of file
+!function(e,t,n){"use strict";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function a(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e){var n=this,r=!1;return t(this).one(c.TRANSITION_END,(function(){r=!0})),setTimeout((function(){r||c.triggerTransitionEnd(n)}),e),this}t=t&&t.hasOwnProperty("default")?t.default:t,n=n&&n.hasOwnProperty("default")?n.default:n;var c={TRANSITION_END:"bsTransitionEnd",getUID:function(e){do{e+=~~(1e6*Math.random())}while(document.getElementById(e));return e},getSelectorFromElement:function(e){var t=e.getAttribute("data-target");if(!t||"#"===t){var n=e.getAttribute("href");t=n&&"#"!==n?n.trim():""}try{return document.querySelector(t)?t:null}catch(e){return null}},getTransitionDurationFromElement:function(e){if(!e)return 0;var n=t(e).css("transition-duration"),r=t(e).css("transition-delay"),a=parseFloat(n),i=parseFloat(r);return a||i?(n=n.split(",")[0],r=r.split(",")[0],1e3*(parseFloat(n)+parseFloat(r))):0},reflow:function(e){return e.offsetHeight},triggerTransitionEnd:function(e){t(e).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(e){return(e[0]||e).nodeType},typeCheckConfig:function(e,t,n){for(var r in n)if(Object.prototype.hasOwnProperty.call(n,r)){var a=n[r],i=t[r],o=i&&c.isElement(i)?"element":(s=i,{}.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase());if(!new RegExp(a).test(o))throw new Error(e.toUpperCase()+': Option "'+r+'" provided type "'+o+'" but expected type "'+a+'".')}var s},findShadowRoot:function(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var t=e.getRootNode();return t instanceof ShadowRoot?t:null}return e instanceof ShadowRoot?e:e.parentNode?c.findShadowRoot(e.parentNode):null},jQueryDetection:function(){if(void 0===t)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1===e[0]&&9===e[1]&&e[2]<1||e[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};c.jQueryDetection(),t.fn.emulateTransitionEnd=l,t.event.special[c.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(e){if(t(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}};var u="alert",d=t.fn[u],f={CLOSE:"close.bs.alert",CLOSED:"closed.bs.alert",CLICK_DATA_API:"click.bs.alert.data-api"},h="alert",p="fade",m="show",g=function(){function e(e){this._element=e}var n=e.prototype;return n.close=function(e){var t=this._element;e&&(t=this._getRootElement(e)),this._triggerCloseEvent(t).isDefaultPrevented()||this._removeElement(t)},n.dispose=function(){t.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(e){var n=c.getSelectorFromElement(e),r=!1;return n&&(r=document.querySelector(n)),r||(r=t(e).closest("."+h)[0]),r},n._triggerCloseEvent=function(e){var n=t.Event(f.CLOSE);return t(e).trigger(n),n},n._removeElement=function(e){var n=this;if(t(e).removeClass(m),t(e).hasClass(p)){var r=c.getTransitionDurationFromElement(e);t(e).one(c.TRANSITION_END,(function(t){return n._destroyElement(e,t)})).emulateTransitionEnd(r)}else this._destroyElement(e)},n._destroyElement=function(e){t(e).detach().trigger(f.CLOSED).remove()},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.alert");a||(a=new e(this),r.data("bs.alert",a)),"close"===n&&a[n](this)}))},e._handleDismiss=function(e){return function(t){t&&t.preventDefault(),e.close(this)}},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}}]),e}();t(document).on(f.CLICK_DATA_API,'[data-dismiss="alert"]',g._handleDismiss(new g)),t.fn[u]=g._jQueryInterface,t.fn[u].Constructor=g,t.fn[u].noConflict=function(){return t.fn[u]=d,g._jQueryInterface};var y=t.fn.button,_="active",v="btn",x="focus",b='[data-toggle^="button"]',M='[data-toggle="buttons"]',w='[data-toggle="button"]',k='[data-toggle="buttons"] .btn',T='input:not([type="hidden"])',L=".active",D=".btn",A={CLICK_DATA_API:"click.bs.button.data-api",FOCUS_BLUR_DATA_API:"focus.bs.button.data-api blur.bs.button.data-api",LOAD_DATA_API:"load.bs.button.data-api"},S=function(){function e(e){this._element=e}var n=e.prototype;return n.toggle=function(){var e=!0,n=!0,r=t(this._element).closest(M)[0];if(r){var a=this._element.querySelector(T);if(a){if("radio"===a.type)if(a.checked&&this._element.classList.contains(_))e=!1;else{var i=r.querySelector(L);i&&t(i).removeClass(_)}else"checkbox"===a.type?"LABEL"===this._element.tagName&&a.checked===this._element.classList.contains(_)&&(e=!1):e=!1;e&&(a.checked=!this._element.classList.contains(_),t(a).trigger("change")),a.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains(_)),e&&t(this._element).toggleClass(_))},n.dispose=function(){t.removeData(this._element,"bs.button"),this._element=null},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.button");r||(r=new e(this),t(this).data("bs.button",r)),"toggle"===n&&r[n]()}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}}]),e}();t(document).on(A.CLICK_DATA_API,b,(function(e){var n=e.target;if(t(n).hasClass(v)||(n=t(n).closest(D)[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))e.preventDefault();else{var r=n.querySelector(T);if(r&&(r.hasAttribute("disabled")||r.classList.contains("disabled")))return void e.preventDefault();S._jQueryInterface.call(t(n),"toggle")}})).on(A.FOCUS_BLUR_DATA_API,b,(function(e){var n=t(e.target).closest(D)[0];t(n).toggleClass(x,/^focus(in)?$/.test(e.type))})),t(window).on(A.LOAD_DATA_API,(function(){for(var e=[].slice.call(document.querySelectorAll(k)),t=0,n=e.length;t<n;t++){var r=e[t],a=r.querySelector(T);a.checked||a.hasAttribute("checked")?r.classList.add(_):r.classList.remove(_)}for(var i=0,o=(e=[].slice.call(document.querySelectorAll(w))).length;i<o;i++){var s=e[i];"true"===s.getAttribute("aria-pressed")?s.classList.add(_):s.classList.remove(_)}})),t.fn.button=S._jQueryInterface,t.fn.button.Constructor=S,t.fn.button.noConflict=function(){return t.fn.button=y,S._jQueryInterface};var Y="carousel",C=".bs.carousel",O=t.fn[Y],E={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},P={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},H="next",j="prev",z="left",I="right",N={SLIDE:"slide"+C,SLID:"slid"+C,KEYDOWN:"keydown"+C,MOUSEENTER:"mouseenter"+C,MOUSELEAVE:"mouseleave"+C,TOUCHSTART:"touchstart"+C,TOUCHMOVE:"touchmove"+C,TOUCHEND:"touchend"+C,POINTERDOWN:"pointerdown"+C,POINTERUP:"pointerup"+C,DRAG_START:"dragstart"+C,LOAD_DATA_API:"load"+C+".data-api",CLICK_DATA_API:"click"+C+".data-api"},F="carousel",R="active",W="slide",B="carousel-item-right",q="carousel-item-left",V="carousel-item-next",U="carousel-item-prev",G="pointer-event",J=".active",Z=".active.carousel-item",$=".carousel-item",X=".carousel-item img",K=".carousel-item-next, .carousel-item-prev",Q=".carousel-indicators",ee="[data-slide], [data-slide-to]",te='[data-ride="carousel"]',ne={TOUCH:"touch",PEN:"pen"},re=function(){function e(e,t){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(t),this._element=e,this._indicatorsElement=this._element.querySelector(Q),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=e.prototype;return n.next=function(){this._isSliding||this._slide(H)},n.nextWhenVisible=function(){!document.hidden&&t(this._element).is(":visible")&&"hidden"!==t(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide(j)},n.pause=function(e){e||(this._isPaused=!0),this._element.querySelector(K)&&(c.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(e){e||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(e){var n=this;this._activeElement=this._element.querySelector(Z);var r=this._getItemIndex(this._activeElement);if(!(e>this._items.length-1||e<0))if(this._isSliding)t(this._element).one(N.SLID,(function(){return n.to(e)}));else{if(r===e)return this.pause(),void this.cycle();var a=e>r?H:j;this._slide(a,this._items[e])}},n.dispose=function(){t(this._element).off(C),t.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(e){return e=s({},E,{},e),c.typeCheckConfig(Y,e,P),e},n._handleSwipe=function(){var e=Math.abs(this.touchDeltaX);if(!(e<=40)){var t=e/this.touchDeltaX;this.touchDeltaX=0,t>0&&this.prev(),t<0&&this.next()}},n._addEventListeners=function(){var e=this;this._config.keyboard&&t(this._element).on(N.KEYDOWN,(function(t){return e._keydown(t)})),"hover"===this._config.pause&&t(this._element).on(N.MOUSEENTER,(function(t){return e.pause(t)})).on(N.MOUSELEAVE,(function(t){return e.cycle(t)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var e=this;if(this._touchSupported){var n=function(t){e._pointerEvent&&ne[t.originalEvent.pointerType.toUpperCase()]?e.touchStartX=t.originalEvent.clientX:e._pointerEvent||(e.touchStartX=t.originalEvent.touches[0].clientX)},r=function(t){e._pointerEvent&&ne[t.originalEvent.pointerType.toUpperCase()]&&(e.touchDeltaX=t.originalEvent.clientX-e.touchStartX),e._handleSwipe(),"hover"===e._config.pause&&(e.pause(),e.touchTimeout&&clearTimeout(e.touchTimeout),e.touchTimeout=setTimeout((function(t){return e.cycle(t)}),500+e._config.interval))};t(this._element.querySelectorAll(X)).on(N.DRAG_START,(function(e){return e.preventDefault()})),this._pointerEvent?(t(this._element).on(N.POINTERDOWN,(function(e){return n(e)})),t(this._element).on(N.POINTERUP,(function(e){return r(e)})),this._element.classList.add(G)):(t(this._element).on(N.TOUCHSTART,(function(e){return n(e)})),t(this._element).on(N.TOUCHMOVE,(function(t){return function(t){t.originalEvent.touches&&t.originalEvent.touches.length>1?e.touchDeltaX=0:e.touchDeltaX=t.originalEvent.touches[0].clientX-e.touchStartX}(t)})),t(this._element).on(N.TOUCHEND,(function(e){return r(e)})))}},n._keydown=function(e){if(!/input|textarea/i.test(e.target.tagName))switch(e.which){case 37:e.preventDefault(),this.prev();break;case 39:e.preventDefault(),this.next()}},n._getItemIndex=function(e){return this._items=e&&e.parentNode?[].slice.call(e.parentNode.querySelectorAll($)):[],this._items.indexOf(e)},n._getItemByDirection=function(e,t){var n=e===H,r=e===j,a=this._getItemIndex(t),i=this._items.length-1;if((r&&0===a||n&&a===i)&&!this._config.wrap)return t;var o=(a+(e===j?-1:1))%this._items.length;return-1===o?this._items[this._items.length-1]:this._items[o]},n._triggerSlideEvent=function(e,n){var r=this._getItemIndex(e),a=this._getItemIndex(this._element.querySelector(Z)),i=t.Event(N.SLIDE,{relatedTarget:e,direction:n,from:a,to:r});return t(this._element).trigger(i),i},n._setActiveIndicatorElement=function(e){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(J));t(n).removeClass(R);var r=this._indicatorsElement.children[this._getItemIndex(e)];r&&t(r).addClass(R)}},n._slide=function(e,n){var r,a,i,o=this,s=this._element.querySelector(Z),l=this._getItemIndex(s),u=n||s&&this._getItemByDirection(e,s),d=this._getItemIndex(u),f=Boolean(this._interval);if(e===H?(r=q,a=V,i=z):(r=B,a=U,i=I),u&&t(u).hasClass(R))this._isSliding=!1;else if(!this._triggerSlideEvent(u,i).isDefaultPrevented()&&s&&u){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(u);var h=t.Event(N.SLID,{relatedTarget:u,direction:i,from:l,to:d});if(t(this._element).hasClass(W)){t(u).addClass(a),c.reflow(u),t(s).addClass(r),t(u).addClass(r);var p=parseInt(u.getAttribute("data-interval"),10);p?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=p):this._config.interval=this._config.defaultInterval||this._config.interval;var m=c.getTransitionDurationFromElement(s);t(s).one(c.TRANSITION_END,(function(){t(u).removeClass(r+" "+a).addClass(R),t(s).removeClass(R+" "+a+" "+r),o._isSliding=!1,setTimeout((function(){return t(o._element).trigger(h)}),0)})).emulateTransitionEnd(m)}else t(s).removeClass(R),t(u).addClass(R),this._isSliding=!1,t(this._element).trigger(h);f&&this.cycle()}},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.carousel"),a=s({},E,{},t(this).data());"object"==typeof n&&(a=s({},a,{},n));var i="string"==typeof n?n:a.slide;if(r||(r=new e(this,a),t(this).data("bs.carousel",r)),"number"==typeof n)r.to(n);else if("string"==typeof i){if(void 0===r[i])throw new TypeError('No method named "'+i+'"');r[i]()}else a.interval&&a.ride&&(r.pause(),r.cycle())}))},e._dataApiClickHandler=function(n){var r=c.getSelectorFromElement(this);if(r){var a=t(r)[0];if(a&&t(a).hasClass(F)){var i=s({},t(a).data(),{},t(this).data()),o=this.getAttribute("data-slide-to");o&&(i.interval=!1),e._jQueryInterface.call(t(a),i),o&&t(a).data("bs.carousel").to(o),n.preventDefault()}}},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return E}}]),e}();t(document).on(N.CLICK_DATA_API,ee,re._dataApiClickHandler),t(window).on(N.LOAD_DATA_API,(function(){for(var e=[].slice.call(document.querySelectorAll(te)),n=0,r=e.length;n<r;n++){var a=t(e[n]);re._jQueryInterface.call(a,a.data())}})),t.fn[Y]=re._jQueryInterface,t.fn[Y].Constructor=re,t.fn[Y].noConflict=function(){return t.fn[Y]=O,re._jQueryInterface};var ae="collapse",ie=t.fn[ae],oe={toggle:!0,parent:""},se={toggle:"boolean",parent:"(string|element)"},le={SHOW:"show.bs.collapse",SHOWN:"shown.bs.collapse",HIDE:"hide.bs.collapse",HIDDEN:"hidden.bs.collapse",CLICK_DATA_API:"click.bs.collapse.data-api"},ce="show",ue="collapse",de="collapsing",fe="collapsed",he="width",pe="height",me=".show, .collapsing",ge='[data-toggle="collapse"]',ye=function(){function e(e,t){this._isTransitioning=!1,this._element=e,this._config=this._getConfig(t),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'));for(var n=[].slice.call(document.querySelectorAll(ge)),r=0,a=n.length;r<a;r++){var i=n[r],o=c.getSelectorFromElement(i),s=[].slice.call(document.querySelectorAll(o)).filter((function(t){return t===e}));null!==o&&s.length>0&&(this._selector=o,this._triggerArray.push(i))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=e.prototype;return n.toggle=function(){t(this._element).hasClass(ce)?this.hide():this.show()},n.show=function(){var n,r,a=this;if(!(this._isTransitioning||t(this._element).hasClass(ce)||(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(me)).filter((function(e){return"string"==typeof a._config.parent?e.getAttribute("data-parent")===a._config.parent:e.classList.contains(ue)}))).length&&(n=null),n&&(r=t(n).not(this._selector).data("bs.collapse"))&&r._isTransitioning))){var i=t.Event(le.SHOW);if(t(this._element).trigger(i),!i.isDefaultPrevented()){n&&(e._jQueryInterface.call(t(n).not(this._selector),"hide"),r||t(n).data("bs.collapse",null));var o=this._getDimension();t(this._element).removeClass(ue).addClass(de),this._element.style[o]=0,this._triggerArray.length&&t(this._triggerArray).removeClass(fe).attr("aria-expanded",!0),this.setTransitioning(!0);var s="scroll"+(o[0].toUpperCase()+o.slice(1)),l=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(){t(a._element).removeClass(de).addClass(ue).addClass(ce),a._element.style[o]="",a.setTransitioning(!1),t(a._element).trigger(le.SHOWN)})).emulateTransitionEnd(l),this._element.style[o]=this._element[s]+"px"}}},n.hide=function(){var e=this;if(!this._isTransitioning&&t(this._element).hasClass(ce)){var n=t.Event(le.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var r=this._getDimension();this._element.style[r]=this._element.getBoundingClientRect()[r]+"px",c.reflow(this._element),t(this._element).addClass(de).removeClass(ue).removeClass(ce);var a=this._triggerArray.length;if(a>0)for(var i=0;i<a;i++){var o=this._triggerArray[i],s=c.getSelectorFromElement(o);null!==s&&(t([].slice.call(document.querySelectorAll(s))).hasClass(ce)||t(o).addClass(fe).attr("aria-expanded",!1))}this.setTransitioning(!0),this._element.style[r]="";var l=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(){e.setTransitioning(!1),t(e._element).removeClass(de).addClass(ue).trigger(le.HIDDEN)})).emulateTransitionEnd(l)}}},n.setTransitioning=function(e){this._isTransitioning=e},n.dispose=function(){t.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(e){return(e=s({},oe,{},e)).toggle=Boolean(e.toggle),c.typeCheckConfig(ae,e,se),e},n._getDimension=function(){return t(this._element).hasClass(he)?he:pe},n._getParent=function(){var n,r=this;c.isElement(this._config.parent)?(n=this._config.parent,void 0!==this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var a='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',i=[].slice.call(n.querySelectorAll(a));return t(i).each((function(t,n){r._addAriaAndCollapsedClass(e._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(e,n){var r=t(e).hasClass(ce);n.length&&t(n).toggleClass(fe,!r).attr("aria-expanded",r)},e._getTargetFromElement=function(e){var t=c.getSelectorFromElement(e);return t?document.querySelector(t):null},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.collapse"),i=s({},oe,{},r.data(),{},"object"==typeof n&&n?n:{});if(!a&&i.toggle&&/show|hide/.test(n)&&(i.toggle=!1),a||(a=new e(this,i),r.data("bs.collapse",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return oe}}]),e}();t(document).on(le.CLICK_DATA_API,ge,(function(e){"A"===e.currentTarget.tagName&&e.preventDefault();var n=t(this),r=c.getSelectorFromElement(this),a=[].slice.call(document.querySelectorAll(r));t(a).each((function(){var e=t(this),r=e.data("bs.collapse")?"toggle":n.data();ye._jQueryInterface.call(e,r)}))})),t.fn[ae]=ye._jQueryInterface,t.fn[ae].Constructor=ye,t.fn[ae].noConflict=function(){return t.fn[ae]=ie,ye._jQueryInterface};var _e="dropdown",ve=t.fn[_e],xe=new RegExp("38|40|27"),be={HIDE:"hide.bs.dropdown",HIDDEN:"hidden.bs.dropdown",SHOW:"show.bs.dropdown",SHOWN:"shown.bs.dropdown",CLICK:"click.bs.dropdown",CLICK_DATA_API:"click.bs.dropdown.data-api",KEYDOWN_DATA_API:"keydown.bs.dropdown.data-api",KEYUP_DATA_API:"keyup.bs.dropdown.data-api"},Me="disabled",we="show",ke="dropup",Te="dropright",Le="dropleft",De="dropdown-menu-right",Ae="position-static",Se='[data-toggle="dropdown"]',Ye=".dropdown form",Ce=".dropdown-menu",Oe=".navbar-nav",Ee=".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",Pe="top-start",He="top-end",je="bottom-start",ze="bottom-end",Ie="right-start",Ne="left-start",Fe={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Re={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},We=function(){function e(e,t){this._element=e,this._popper=null,this._config=this._getConfig(t),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var r=e.prototype;return r.toggle=function(){if(!this._element.disabled&&!t(this._element).hasClass(Me)){var n=t(this._menu).hasClass(we);e._clearMenus(),n||this.show(!0)}},r.show=function(r){if(void 0===r&&(r=!1),!(this._element.disabled||t(this._element).hasClass(Me)||t(this._menu).hasClass(we))){var a={relatedTarget:this._element},i=t.Event(be.SHOW,a),o=e._getParentFromElement(this._element);if(t(o).trigger(i),!i.isDefaultPrevented()){if(!this._inNavbar&&r){if(void 0===n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var s=this._element;"parent"===this._config.reference?s=o:c.isElement(this._config.reference)&&(s=this._config.reference,void 0!==this._config.reference.jquery&&(s=this._config.reference[0])),"scrollParent"!==this._config.boundary&&t(o).addClass(Ae),this._popper=new n(s,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===t(o).closest(Oe).length&&t(document.body).children().on("mouseover",null,t.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),t(this._menu).toggleClass(we),t(o).toggleClass(we).trigger(t.Event(be.SHOWN,a))}}},r.hide=function(){if(!this._element.disabled&&!t(this._element).hasClass(Me)&&t(this._menu).hasClass(we)){var n={relatedTarget:this._element},r=t.Event(be.HIDE,n),a=e._getParentFromElement(this._element);t(a).trigger(r),r.isDefaultPrevented()||(this._popper&&this._popper.destroy(),t(this._menu).toggleClass(we),t(a).toggleClass(we).trigger(t.Event(be.HIDDEN,n)))}},r.dispose=function(){t.removeData(this._element,"bs.dropdown"),t(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},r.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},r._addEventListeners=function(){var e=this;t(this._element).on(be.CLICK,(function(t){t.preventDefault(),t.stopPropagation(),e.toggle()}))},r._getConfig=function(e){return e=s({},this.constructor.Default,{},t(this._element).data(),{},e),c.typeCheckConfig(_e,e,this.constructor.DefaultType),e},r._getMenuElement=function(){if(!this._menu){var t=e._getParentFromElement(this._element);t&&(this._menu=t.querySelector(Ce))}return this._menu},r._getPlacement=function(){var e=t(this._element.parentNode),n=je;return e.hasClass(ke)?(n=Pe,t(this._menu).hasClass(De)&&(n=He)):e.hasClass(Te)?n=Ie:e.hasClass(Le)?n=Ne:t(this._menu).hasClass(De)&&(n=ze),n},r._detectNavbar=function(){return t(this._element).closest(".navbar").length>0},r._getOffset=function(){var e=this,t={};return"function"==typeof this._config.offset?t.fn=function(t){return t.offsets=s({},t.offsets,{},e._config.offset(t.offsets,e._element)||{}),t}:t.offset=this._config.offset,t},r._getPopperConfig=function(){var e={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(e.modifiers.applyStyle={enabled:!1}),s({},e,{},this._config.popperConfig)},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.dropdown");if(r||(r=new e(this,"object"==typeof n?n:null),t(this).data("bs.dropdown",r)),"string"==typeof n){if(void 0===r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},e._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var r=[].slice.call(document.querySelectorAll(Se)),a=0,i=r.length;a<i;a++){var o=e._getParentFromElement(r[a]),s=t(r[a]).data("bs.dropdown"),l={relatedTarget:r[a]};if(n&&"click"===n.type&&(l.clickEvent=n),s){var c=s._menu;if(t(o).hasClass(we)&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&t.contains(o,n.target))){var u=t.Event(be.HIDE,l);t(o).trigger(u),u.isDefaultPrevented()||("ontouchstart"in document.documentElement&&t(document.body).children().off("mouseover",null,t.noop),r[a].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),t(c).removeClass(we),t(o).removeClass(we).trigger(t.Event(be.HIDDEN,l)))}}}},e._getParentFromElement=function(e){var t,n=c.getSelectorFromElement(e);return n&&(t=document.querySelector(n)),t||e.parentNode},e._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||t(n.target).closest(Ce).length):!xe.test(n.which))&&(n.preventDefault(),n.stopPropagation(),!this.disabled&&!t(this).hasClass(Me))){var r=e._getParentFromElement(this),a=t(r).hasClass(we);if(a||27!==n.which)if(a&&(!a||27!==n.which&&32!==n.which)){var i=[].slice.call(r.querySelectorAll(Ee)).filter((function(e){return t(e).is(":visible")}));if(0!==i.length){var o=i.indexOf(n.target);38===n.which&&o>0&&o--,40===n.which&&o<i.length-1&&o++,o<0&&(o=0),i[o].focus()}}else{if(27===n.which){var s=r.querySelector(Se);t(s).trigger("focus")}t(this).trigger("click")}}},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return Fe}},{key:"DefaultType",get:function(){return Re}}]),e}();t(document).on(be.KEYDOWN_DATA_API,Se,We._dataApiKeydownHandler).on(be.KEYDOWN_DATA_API,Ce,We._dataApiKeydownHandler).on(be.CLICK_DATA_API+" "+be.KEYUP_DATA_API,We._clearMenus).on(be.CLICK_DATA_API,Se,(function(e){e.preventDefault(),e.stopPropagation(),We._jQueryInterface.call(t(this),"toggle")})).on(be.CLICK_DATA_API,Ye,(function(e){e.stopPropagation()})),t.fn[_e]=We._jQueryInterface,t.fn[_e].Constructor=We,t.fn[_e].noConflict=function(){return t.fn[_e]=ve,We._jQueryInterface};var Be=t.fn.modal,qe={backdrop:!0,keyboard:!0,focus:!0,show:!0},Ve={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Ue={HIDE:"hide.bs.modal",HIDE_PREVENTED:"hidePrevented.bs.modal",HIDDEN:"hidden.bs.modal",SHOW:"show.bs.modal",SHOWN:"shown.bs.modal",FOCUSIN:"focusin.bs.modal",RESIZE:"resize.bs.modal",CLICK_DISMISS:"click.dismiss.bs.modal",KEYDOWN_DISMISS:"keydown.dismiss.bs.modal",MOUSEUP_DISMISS:"mouseup.dismiss.bs.modal",MOUSEDOWN_DISMISS:"mousedown.dismiss.bs.modal",CLICK_DATA_API:"click.bs.modal.data-api"},Ge="modal-dialog-scrollable",Je="modal-scrollbar-measure",Ze="modal-backdrop",$e="modal-open",Xe="fade",Ke="show",Qe="modal-static",et=".modal-dialog",tt=".modal-body",nt='[data-toggle="modal"]',rt='[data-dismiss="modal"]',at=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",it=".sticky-top",ot=function(){function e(e,t){this._config=this._getConfig(t),this._element=e,this._dialog=e.querySelector(et),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=e.prototype;return n.toggle=function(e){return this._isShown?this.hide():this.show(e)},n.show=function(e){var n=this;if(!this._isShown&&!this._isTransitioning){t(this._element).hasClass(Xe)&&(this._isTransitioning=!0);var r=t.Event(Ue.SHOW,{relatedTarget:e});t(this._element).trigger(r),this._isShown||r.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),t(this._element).on(Ue.CLICK_DISMISS,rt,(function(e){return n.hide(e)})),t(this._dialog).on(Ue.MOUSEDOWN_DISMISS,(function(){t(n._element).one(Ue.MOUSEUP_DISMISS,(function(e){t(e.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(e)})))}},n.hide=function(e){var n=this;if(e&&e.preventDefault(),this._isShown&&!this._isTransitioning){var r=t.Event(Ue.HIDE);if(t(this._element).trigger(r),this._isShown&&!r.isDefaultPrevented()){this._isShown=!1;var a=t(this._element).hasClass(Xe);if(a&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),t(document).off(Ue.FOCUSIN),t(this._element).removeClass(Ke),t(this._element).off(Ue.CLICK_DISMISS),t(this._dialog).off(Ue.MOUSEDOWN_DISMISS),a){var i=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(e){return n._hideModal(e)})).emulateTransitionEnd(i)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(e){return t(e).off(".bs.modal")})),t(document).off(Ue.FOCUSIN),t.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(e){return e=s({},qe,{},e),c.typeCheckConfig("modal",e,Ve),e},n._triggerBackdropTransition=function(){var e=this;if("static"===this._config.backdrop){var n=t.Event(Ue.HIDE_PREVENTED);if(t(this._element).trigger(n),n.defaultPrevented)return;this._element.classList.add(Qe);var r=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,(function(){e._element.classList.remove(Qe)})).emulateTransitionEnd(r),this._element.focus()}else this.hide()},n._showElement=function(e){var n=this,r=t(this._element).hasClass(Xe),a=this._dialog?this._dialog.querySelector(tt):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),t(this._dialog).hasClass(Ge)&&a?a.scrollTop=0:this._element.scrollTop=0,r&&c.reflow(this._element),t(this._element).addClass(Ke),this._config.focus&&this._enforceFocus();var i=t.Event(Ue.SHOWN,{relatedTarget:e}),o=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,t(n._element).trigger(i)};if(r){var s=c.getTransitionDurationFromElement(this._dialog);t(this._dialog).one(c.TRANSITION_END,o).emulateTransitionEnd(s)}else o()},n._enforceFocus=function(){var e=this;t(document).off(Ue.FOCUSIN).on(Ue.FOCUSIN,(function(n){document!==n.target&&e._element!==n.target&&0===t(e._element).has(n.target).length&&e._element.focus()}))},n._setEscapeEvent=function(){var e=this;this._isShown&&this._config.keyboard?t(this._element).on(Ue.KEYDOWN_DISMISS,(function(t){27===t.which&&e._triggerBackdropTransition()})):this._isShown||t(this._element).off(Ue.KEYDOWN_DISMISS)},n._setResizeEvent=function(){var e=this;this._isShown?t(window).on(Ue.RESIZE,(function(t){return e.handleUpdate(t)})):t(window).off(Ue.RESIZE)},n._hideModal=function(){var e=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._isTransitioning=!1,this._showBackdrop((function(){t(document.body).removeClass($e),e._resetAdjustments(),e._resetScrollbar(),t(e._element).trigger(Ue.HIDDEN)}))},n._removeBackdrop=function(){this._backdrop&&(t(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(e){var n=this,r=t(this._element).hasClass(Xe)?Xe:"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className=Ze,r&&this._backdrop.classList.add(r),t(this._backdrop).appendTo(document.body),t(this._element).on(Ue.CLICK_DISMISS,(function(e){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:e.target===e.currentTarget&&n._triggerBackdropTransition()})),r&&c.reflow(this._backdrop),t(this._backdrop).addClass(Ke),!e)return;if(!r)return void e();var a=c.getTransitionDurationFromElement(this._backdrop);t(this._backdrop).one(c.TRANSITION_END,e).emulateTransitionEnd(a)}else if(!this._isShown&&this._backdrop){t(this._backdrop).removeClass(Ke);var i=function(){n._removeBackdrop(),e&&e()};if(t(this._element).hasClass(Xe)){var o=c.getTransitionDurationFromElement(this._backdrop);t(this._backdrop).one(c.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}else e&&e()},n._adjustDialog=function(){var e=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&e&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!e&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var e=document.body.getBoundingClientRect();this._isBodyOverflowing=e.left+e.right<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var e=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(at)),r=[].slice.call(document.querySelectorAll(it));t(n).each((function(n,r){var a=r.style.paddingRight,i=t(r).css("padding-right");t(r).data("padding-right",a).css("padding-right",parseFloat(i)+e._scrollbarWidth+"px")})),t(r).each((function(n,r){var a=r.style.marginRight,i=t(r).css("margin-right");t(r).data("margin-right",a).css("margin-right",parseFloat(i)-e._scrollbarWidth+"px")}));var a=document.body.style.paddingRight,i=t(document.body).css("padding-right");t(document.body).data("padding-right",a).css("padding-right",parseFloat(i)+this._scrollbarWidth+"px")}t(document.body).addClass($e)},n._resetScrollbar=function(){var e=[].slice.call(document.querySelectorAll(at));t(e).each((function(e,n){var r=t(n).data("padding-right");t(n).removeData("padding-right"),n.style.paddingRight=r||""}));var n=[].slice.call(document.querySelectorAll(""+it));t(n).each((function(e,n){var r=t(n).data("margin-right");void 0!==r&&t(n).css("margin-right",r).removeData("margin-right")}));var r=t(document.body).data("padding-right");t(document.body).removeData("padding-right"),document.body.style.paddingRight=r||""},n._getScrollbarWidth=function(){var e=document.createElement("div");e.className=Je,document.body.appendChild(e);var t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},e._jQueryInterface=function(n,r){return this.each((function(){var a=t(this).data("bs.modal"),i=s({},qe,{},t(this).data(),{},"object"==typeof n&&n?n:{});if(a||(a=new e(this,i),t(this).data("bs.modal",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n](r)}else i.show&&a.show(r)}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return qe}}]),e}();t(document).on(Ue.CLICK_DATA_API,nt,(function(e){var n,r=this,a=c.getSelectorFromElement(this);a&&(n=document.querySelector(a));var i=t(n).data("bs.modal")?"toggle":s({},t(n).data(),{},t(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||e.preventDefault();var o=t(n).one(Ue.SHOW,(function(e){e.isDefaultPrevented()||o.one(Ue.HIDDEN,(function(){t(r).is(":visible")&&r.focus()}))}));ot._jQueryInterface.call(t(n),i,this)})),t.fn.modal=ot._jQueryInterface,t.fn.modal.Constructor=ot,t.fn.modal.noConflict=function(){return t.fn.modal=Be,ot._jQueryInterface};var st=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],lt={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},ct=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,ut=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function dt(e,t,n){if(0===e.length)return e;if(n&&"function"==typeof n)return n(e);for(var r=(new window.DOMParser).parseFromString(e,"text/html"),a=Object.keys(t),i=[].slice.call(r.body.querySelectorAll("*")),o=function(e,n){var r=i[e],o=r.nodeName.toLowerCase();if(-1===a.indexOf(r.nodeName.toLowerCase()))return r.parentNode.removeChild(r),"continue";var s=[].slice.call(r.attributes),l=[].concat(t["*"]||[],t[o]||[]);s.forEach((function(e){(function(e,t){var n=e.nodeName.toLowerCase();if(-1!==t.indexOf(n))return-1===st.indexOf(n)||Boolean(e.nodeValue.match(ct)||e.nodeValue.match(ut));for(var r=t.filter((function(e){return e instanceof RegExp})),a=0,i=r.length;a<i;a++)if(n.match(r[a]))return!0;return!1})(e,l)||r.removeAttribute(e.nodeName)}))},s=0,l=i.length;s<l;s++)o(s);return r.body.innerHTML}var ft="tooltip",ht=t.fn[ft],pt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),mt=["sanitize","whiteList","sanitizeFn"],gt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},yt={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},_t={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:lt,popperConfig:null},vt="show",xt="out",bt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Mt="fade",wt="show",kt=".tooltip-inner",Tt=".arrow",Lt="hover",Dt="focus",At="click",St="manual",Yt=function(){function e(e,t){if(void 0===n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var r=e.prototype;return r.enable=function(){this._isEnabled=!0},r.disable=function(){this._isEnabled=!1},r.toggleEnabled=function(){this._isEnabled=!this._isEnabled},r.toggle=function(e){if(this._isEnabled)if(e){var n=this.constructor.DATA_KEY,r=t(e.currentTarget).data(n);r||(r=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,r)),r._activeTrigger.click=!r._activeTrigger.click,r._isWithActiveTrigger()?r._enter(null,r):r._leave(null,r)}else{if(t(this.getTipElement()).hasClass(wt))return void this._leave(null,this);this._enter(null,this)}},r.dispose=function(){clearTimeout(this._timeout),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),t(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},r.show=function(){var e=this;if("none"===t(this.element).css("display"))throw new Error("Please use show on visible elements");var r=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){t(this.element).trigger(r);var a=c.findShadowRoot(this.element),i=t.contains(null!==a?a:this.element.ownerDocument.documentElement,this.element);if(r.isDefaultPrevented()||!i)return;var o=this.getTipElement(),s=c.getUID(this.constructor.NAME);o.setAttribute("id",s),this.element.setAttribute("aria-describedby",s),this.setContent(),this.config.animation&&t(o).addClass(Mt);var l="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,u=this._getAttachment(l);this.addAttachmentClass(u);var d=this._getContainer();t(o).data(this.constructor.DATA_KEY,this),t.contains(this.element.ownerDocument.documentElement,this.tip)||t(o).appendTo(d),t(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,o,this._getPopperConfig(u)),t(o).addClass(wt),"ontouchstart"in document.documentElement&&t(document.body).children().on("mouseover",null,t.noop);var f=function(){e.config.animation&&e._fixTransition();var n=e._hoverState;e._hoverState=null,t(e.element).trigger(e.constructor.Event.SHOWN),n===xt&&e._leave(null,e)};if(t(this.tip).hasClass(Mt)){var h=c.getTransitionDurationFromElement(this.tip);t(this.tip).one(c.TRANSITION_END,f).emulateTransitionEnd(h)}else f()}},r.hide=function(e){var n=this,r=this.getTipElement(),a=t.Event(this.constructor.Event.HIDE),i=function(){n._hoverState!==vt&&r.parentNode&&r.parentNode.removeChild(r),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()};if(t(this.element).trigger(a),!a.isDefaultPrevented()){if(t(r).removeClass(wt),"ontouchstart"in document.documentElement&&t(document.body).children().off("mouseover",null,t.noop),this._activeTrigger[At]=!1,this._activeTrigger[Dt]=!1,this._activeTrigger[Lt]=!1,t(this.tip).hasClass(Mt)){var o=c.getTransitionDurationFromElement(r);t(r).one(c.TRANSITION_END,i).emulateTransitionEnd(o)}else i();this._hoverState=""}},r.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},r.isWithContent=function(){return Boolean(this.getTitle())},r.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-tooltip-"+e)},r.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},r.setContent=function(){var e=this.getTipElement();this.setElementContent(t(e.querySelectorAll(kt)),this.getTitle()),t(e).removeClass(Mt+" "+wt)},r.setElementContent=function(e,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=dt(n,this.config.whiteList,this.config.sanitizeFn)),e.html(n)):e.text(n):this.config.html?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text())},r.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e||(e="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),e},r._getPopperConfig=function(e){var t=this;return s({},{placement:e,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Tt},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){return t._handlePopperPlacementChange(e)}},{},this.config.popperConfig)},r._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=s({},t.offsets,{},e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},r._getContainer=function(){return!1===this.config.container?document.body:c.isElement(this.config.container)?t(this.config.container):t(document).find(this.config.container)},r._getAttachment=function(e){return yt[e.toUpperCase()]},r._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,(function(t){return e.toggle(t)}));else if(n!==St){var r=n===Lt?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,a=n===Lt?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(r,e.config.selector,(function(t){return e._enter(t)})).on(a,e.config.selector,(function(t){return e._leave(t)}))}})),this._hideModalHandler=function(){e.element&&e.hide()},t(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},r._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==e)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},r._enter=function(e,n){var r=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(r))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(r,n)),e&&(n._activeTrigger["focusin"===e.type?Dt:Lt]=!0),t(n.getTipElement()).hasClass(wt)||n._hoverState===vt?n._hoverState=vt:(clearTimeout(n._timeout),n._hoverState=vt,n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){n._hoverState===vt&&n.show()}),n.config.delay.show):n.show())},r._leave=function(e,n){var r=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(r))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(r,n)),e&&(n._activeTrigger["focusout"===e.type?Dt:Lt]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState=xt,n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){n._hoverState===xt&&n.hide()}),n.config.delay.hide):n.hide())},r._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},r._getConfig=function(e){var n=t(this.element).data();return Object.keys(n).forEach((function(e){-1!==mt.indexOf(e)&&delete n[e]})),"number"==typeof(e=s({},this.constructor.Default,{},n,{},"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),c.typeCheckConfig(ft,e,this.constructor.DefaultType),e.sanitize&&(e.template=dt(e.template,e.whiteList,e.sanitizeFn)),e},r._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},r._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(pt);null!==n&&n.length&&e.removeClass(n.join(""))},r._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},r._fixTransition=function(){var e=this.getTipElement(),n=this.config.animation;null===e.getAttribute("x-placement")&&(t(e).removeClass(Mt),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.tooltip"),a="object"==typeof n&&n;if((r||!/dispose|hide/.test(n))&&(r||(r=new e(this,a),t(this).data("bs.tooltip",r)),"string"==typeof n)){if(void 0===r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return _t}},{key:"NAME",get:function(){return ft}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return bt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return gt}}]),e}();t.fn[ft]=Yt._jQueryInterface,t.fn[ft].Constructor=Yt,t.fn[ft].noConflict=function(){return t.fn[ft]=ht,Yt._jQueryInterface};var Ct="popover",Ot=t.fn[Ct],Et=new RegExp("(^|\\s)bs-popover\\S+","g"),Pt=s({},Yt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Ht=s({},Yt.DefaultType,{content:"(string|element|function)"}),jt="fade",zt="show",It=".popover-header",Nt=".popover-body",Ft={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Rt=function(e){var n,r;function i(){return e.apply(this,arguments)||this}r=e,(n=i).prototype=Object.create(r.prototype),n.prototype.constructor=n,n.__proto__=r;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-popover-"+e)},o.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},o.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(It),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(e.find(Nt),n),e.removeClass(jt+" "+zt)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(Et);null!==n&&n.length>0&&e.removeClass(n.join(""))},i._jQueryInterface=function(e){return this.each((function(){var n=t(this).data("bs.popover"),r="object"==typeof e?e:null;if((n||!/dispose|hide/.test(e))&&(n||(n=new i(this,r),t(this).data("bs.popover",n)),"string"==typeof e)){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}}))},a(i,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return Pt}},{key:"NAME",get:function(){return Ct}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return Ft}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Ht}}]),i}(Yt);t.fn[Ct]=Rt._jQueryInterface,t.fn[Ct].Constructor=Rt,t.fn[Ct].noConflict=function(){return t.fn[Ct]=Ot,Rt._jQueryInterface};var Wt="scrollspy",Bt=t.fn[Wt],qt={offset:10,method:"auto",target:""},Vt={offset:"number",method:"string",target:"(string|element)"},Ut={ACTIVATE:"activate.bs.scrollspy",SCROLL:"scroll.bs.scrollspy",LOAD_DATA_API:"load.bs.scrollspy.data-api"},Gt="dropdown-item",Jt="active",Zt='[data-spy="scroll"]',$t=".nav, .list-group",Xt=".nav-link",Kt=".nav-item",Qt=".list-group-item",en=".dropdown",tn=".dropdown-item",nn=".dropdown-toggle",rn="offset",an="position",on=function(){function e(e,n){var r=this;this._element=e,this._scrollElement="BODY"===e.tagName?window:e,this._config=this._getConfig(n),this._selector=this._config.target+" "+Xt+","+this._config.target+" "+Qt+","+this._config.target+" "+tn,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,t(this._scrollElement).on(Ut.SCROLL,(function(e){return r._process(e)})),this.refresh(),this._process()}var n=e.prototype;return n.refresh=function(){var e=this,n=this._scrollElement===this._scrollElement.window?rn:an,r="auto"===this._config.method?n:this._config.method,a=r===an?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(e){var n,i=c.getSelectorFromElement(e);if(i&&(n=document.querySelector(i)),n){var o=n.getBoundingClientRect();if(o.width||o.height)return[t(n)[r]().top+a,i]}return null})).filter((function(e){return e})).sort((function(e,t){return e[0]-t[0]})).forEach((function(t){e._offsets.push(t[0]),e._targets.push(t[1])}))},n.dispose=function(){t.removeData(this._element,"bs.scrollspy"),t(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(e){if("string"!=typeof(e=s({},qt,{},"object"==typeof e&&e?e:{})).target){var n=t(e.target).attr("id");n||(n=c.getUID(Wt),t(e.target).attr("id",n)),e.target="#"+n}return c.typeCheckConfig(Wt,e,Vt),e},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var e=this._getScrollTop()+this._config.offset,t=this._getScrollHeight(),n=this._config.offset+t-this._getOffsetHeight();if(this._scrollHeight!==t&&this.refresh(),e>=n){var r=this._targets[this._targets.length-1];this._activeTarget!==r&&this._activate(r)}else{if(this._activeTarget&&e<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var a=this._offsets.length;a--;)this._activeTarget!==this._targets[a]&&e>=this._offsets[a]&&(void 0===this._offsets[a+1]||e<this._offsets[a+1])&&this._activate(this._targets[a])}},n._activate=function(e){this._activeTarget=e,this._clear();var n=this._selector.split(",").map((function(t){return t+'[data-target="'+e+'"],'+t+'[href="'+e+'"]'})),r=t([].slice.call(document.querySelectorAll(n.join(","))));r.hasClass(Gt)?(r.closest(en).find(nn).addClass(Jt),r.addClass(Jt)):(r.addClass(Jt),r.parents($t).prev(Xt+", "+Qt).addClass(Jt),r.parents($t).prev(Kt).children(Xt).addClass(Jt)),t(this._scrollElement).trigger(Ut.ACTIVATE,{relatedTarget:e})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(e){return e.classList.contains(Jt)})).forEach((function(e){return e.classList.remove(Jt)}))},e._jQueryInterface=function(n){return this.each((function(){var r=t(this).data("bs.scrollspy");if(r||(r=new e(this,"object"==typeof n&&n),t(this).data("bs.scrollspy",r)),"string"==typeof n){if(void 0===r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"Default",get:function(){return qt}}]),e}();t(window).on(Ut.LOAD_DATA_API,(function(){for(var e=[].slice.call(document.querySelectorAll(Zt)),n=e.length;n--;){var r=t(e[n]);on._jQueryInterface.call(r,r.data())}})),t.fn[Wt]=on._jQueryInterface,t.fn[Wt].Constructor=on,t.fn[Wt].noConflict=function(){return t.fn[Wt]=Bt,on._jQueryInterface};var sn=t.fn.tab,ln={HIDE:"hide.bs.tab",HIDDEN:"hidden.bs.tab",SHOW:"show.bs.tab",SHOWN:"shown.bs.tab",CLICK_DATA_API:"click.bs.tab.data-api"},cn="dropdown-menu",un="active",dn="disabled",fn="fade",hn="show",pn=".dropdown",mn=".nav, .list-group",gn=".active",yn="> li > .active",_n='[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',vn=".dropdown-toggle",xn="> .dropdown-menu .active",bn=function(){function e(e){this._element=e}var n=e.prototype;return n.show=function(){var e=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&t(this._element).hasClass(un)||t(this._element).hasClass(dn))){var n,r,a=t(this._element).closest(mn)[0],i=c.getSelectorFromElement(this._element);if(a){var o="UL"===a.nodeName||"OL"===a.nodeName?yn:gn;r=(r=t.makeArray(t(a).find(o)))[r.length-1]}var s=t.Event(ln.HIDE,{relatedTarget:this._element}),l=t.Event(ln.SHOW,{relatedTarget:r});if(r&&t(r).trigger(s),t(this._element).trigger(l),!l.isDefaultPrevented()&&!s.isDefaultPrevented()){i&&(n=document.querySelector(i)),this._activate(this._element,a);var u=function(){var n=t.Event(ln.HIDDEN,{relatedTarget:e._element}),a=t.Event(ln.SHOWN,{relatedTarget:r});t(r).trigger(n),t(e._element).trigger(a)};n?this._activate(n,n.parentNode,u):u()}}},n.dispose=function(){t.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(e,n,r){var a=this,i=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?t(n).children(gn):t(n).find(yn))[0],o=r&&i&&t(i).hasClass(fn),s=function(){return a._transitionComplete(e,i,r)};if(i&&o){var l=c.getTransitionDurationFromElement(i);t(i).removeClass(hn).one(c.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},n._transitionComplete=function(e,n,r){if(n){t(n).removeClass(un);var a=t(n.parentNode).find(xn)[0];a&&t(a).removeClass(un),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(t(e).addClass(un),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!0),c.reflow(e),e.classList.contains(fn)&&e.classList.add(hn),e.parentNode&&t(e.parentNode).hasClass(cn)){var i=t(e).closest(pn)[0];if(i){var o=[].slice.call(i.querySelectorAll(vn));t(o).addClass(un)}e.setAttribute("aria-expanded",!0)}r&&r()},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.tab");if(a||(a=new e(this),r.data("bs.tab",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n]()}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}}]),e}();t(document).on(ln.CLICK_DATA_API,_n,(function(e){e.preventDefault(),bn._jQueryInterface.call(t(this),"show")})),t.fn.tab=bn._jQueryInterface,t.fn.tab.Constructor=bn,t.fn.tab.noConflict=function(){return t.fn.tab=sn,bn._jQueryInterface};var Mn=t.fn.toast,wn={CLICK_DISMISS:"click.dismiss.bs.toast",HIDE:"hide.bs.toast",HIDDEN:"hidden.bs.toast",SHOW:"show.bs.toast",SHOWN:"shown.bs.toast"},kn="fade",Tn="hide",Ln="show",Dn="showing",An={animation:"boolean",autohide:"boolean",delay:"number"},Sn={animation:!0,autohide:!0,delay:500},Yn='[data-dismiss="toast"]',Cn=function(){function e(e,t){this._element=e,this._config=this._getConfig(t),this._timeout=null,this._setListeners()}var n=e.prototype;return n.show=function(){var e=this,n=t.Event(wn.SHOW);if(t(this._element).trigger(n),!n.isDefaultPrevented()){this._config.animation&&this._element.classList.add(kn);var r=function(){e._element.classList.remove(Dn),e._element.classList.add(Ln),t(e._element).trigger(wn.SHOWN),e._config.autohide&&(e._timeout=setTimeout((function(){e.hide()}),e._config.delay))};if(this._element.classList.remove(Tn),c.reflow(this._element),this._element.classList.add(Dn),this._config.animation){var a=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}},n.hide=function(){if(this._element.classList.contains(Ln)){var e=t.Event(wn.HIDE);t(this._element).trigger(e),e.isDefaultPrevented()||this._close()}},n.dispose=function(){clearTimeout(this._timeout),this._timeout=null,this._element.classList.contains(Ln)&&this._element.classList.remove(Ln),t(this._element).off(wn.CLICK_DISMISS),t.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(e){return e=s({},Sn,{},t(this._element).data(),{},"object"==typeof e&&e?e:{}),c.typeCheckConfig("toast",e,this.constructor.DefaultType),e},n._setListeners=function(){var e=this;t(this._element).on(wn.CLICK_DISMISS,Yn,(function(){return e.hide()}))},n._close=function(){var e=this,n=function(){e._element.classList.add(Tn),t(e._element).trigger(wn.HIDDEN)};if(this._element.classList.remove(Ln),this._config.animation){var r=c.getTransitionDurationFromElement(this._element);t(this._element).one(c.TRANSITION_END,n).emulateTransitionEnd(r)}else n()},e._jQueryInterface=function(n){return this.each((function(){var r=t(this),a=r.data("bs.toast");if(a||(a=new e(this,"object"==typeof n&&n),r.data("bs.toast",a)),"string"==typeof n){if(void 0===a[n])throw new TypeError('No method named "'+n+'"');a[n](this)}}))},a(e,null,[{key:"VERSION",get:function(){return"4.4.1"}},{key:"DefaultType",get:function(){return An}},{key:"Default",get:function(){return Sn}}]),e}();t.fn.toast=Cn._jQueryInterface,t.fn.toast.Constructor=Cn,t.fn.toast.noConflict=function(){return t.fn.toast=Mn,Cn._jQueryInterface},e.Alert=g,e.Button=S,e.Carousel=re,e.Collapse=ye,e.Dropdown=We,e.Modal=ot,e.Popover=Rt,e.Scrollspy=on,e.Tab=bn,e.Toast=Cn,e.Tooltip=Yt,e.Util=c,Object.defineProperty(e,"__esModule",{value:!0})}(t,n(1),n(3))},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t,n){var r={"./af":4,"./af.js":4,"./ar":5,"./ar-dz":6,"./ar-dz.js":6,"./ar-kw":7,"./ar-kw.js":7,"./ar-ly":8,"./ar-ly.js":8,"./ar-ma":9,"./ar-ma.js":9,"./ar-sa":10,"./ar-sa.js":10,"./ar-tn":11,"./ar-tn.js":11,"./ar.js":5,"./az":12,"./az.js":12,"./be":13,"./be.js":13,"./bg":14,"./bg.js":14,"./bm":15,"./bm.js":15,"./bn":16,"./bn.js":16,"./bo":17,"./bo.js":17,"./br":18,"./br.js":18,"./bs":19,"./bs.js":19,"./ca":20,"./ca.js":20,"./cs":21,"./cs.js":21,"./cv":22,"./cv.js":22,"./cy":23,"./cy.js":23,"./da":24,"./da.js":24,"./de":25,"./de-at":26,"./de-at.js":26,"./de-ch":27,"./de-ch.js":27,"./de.js":25,"./dv":28,"./dv.js":28,"./el":29,"./el.js":29,"./en-SG":30,"./en-SG.js":30,"./en-au":31,"./en-au.js":31,"./en-ca":32,"./en-ca.js":32,"./en-gb":33,"./en-gb.js":33,"./en-ie":34,"./en-ie.js":34,"./en-il":35,"./en-il.js":35,"./en-nz":36,"./en-nz.js":36,"./eo":37,"./eo.js":37,"./es":38,"./es-do":39,"./es-do.js":39,"./es-us":40,"./es-us.js":40,"./es.js":38,"./et":41,"./et.js":41,"./eu":42,"./eu.js":42,"./fa":43,"./fa.js":43,"./fi":44,"./fi.js":44,"./fo":45,"./fo.js":45,"./fr":46,"./fr-ca":47,"./fr-ca.js":47,"./fr-ch":48,"./fr-ch.js":48,"./fr.js":46,"./fy":49,"./fy.js":49,"./ga":50,"./ga.js":50,"./gd":51,"./gd.js":51,"./gl":52,"./gl.js":52,"./gom-latn":53,"./gom-latn.js":53,"./gu":54,"./gu.js":54,"./he":55,"./he.js":55,"./hi":56,"./hi.js":56,"./hr":57,"./hr.js":57,"./hu":58,"./hu.js":58,"./hy-am":59,"./hy-am.js":59,"./id":60,"./id.js":60,"./is":61,"./is.js":61,"./it":62,"./it-ch":63,"./it-ch.js":63,"./it.js":62,"./ja":64,"./ja.js":64,"./jv":65,"./jv.js":65,"./ka":66,"./ka.js":66,"./kk":67,"./kk.js":67,"./km":68,"./km.js":68,"./kn":69,"./kn.js":69,"./ko":70,"./ko.js":70,"./ku":71,"./ku.js":71,"./ky":72,"./ky.js":72,"./lb":73,"./lb.js":73,"./lo":74,"./lo.js":74,"./lt":75,"./lt.js":75,"./lv":76,"./lv.js":76,"./me":77,"./me.js":77,"./mi":78,"./mi.js":78,"./mk":79,"./mk.js":79,"./ml":80,"./ml.js":80,"./mn":81,"./mn.js":81,"./mr":82,"./mr.js":82,"./ms":83,"./ms-my":84,"./ms-my.js":84,"./ms.js":83,"./mt":85,"./mt.js":85,"./my":86,"./my.js":86,"./nb":87,"./nb.js":87,"./ne":88,"./ne.js":88,"./nl":89,"./nl-be":90,"./nl-be.js":90,"./nl.js":89,"./nn":91,"./nn.js":91,"./pa-in":92,"./pa-in.js":92,"./pl":93,"./pl.js":93,"./pt":94,"./pt-br":95,"./pt-br.js":95,"./pt.js":94,"./ro":96,"./ro.js":96,"./ru":97,"./ru.js":97,"./sd":98,"./sd.js":98,"./se":99,"./se.js":99,"./si":100,"./si.js":100,"./sk":101,"./sk.js":101,"./sl":102,"./sl.js":102,"./sq":103,"./sq.js":103,"./sr":104,"./sr-cyrl":105,"./sr-cyrl.js":105,"./sr.js":104,"./ss":106,"./ss.js":106,"./sv":107,"./sv.js":107,"./sw":108,"./sw.js":108,"./ta":109,"./ta.js":109,"./te":110,"./te.js":110,"./tet":111,"./tet.js":111,"./tg":112,"./tg.js":112,"./th":113,"./th.js":113,"./tl-ph":114,"./tl-ph.js":114,"./tlh":115,"./tlh.js":115,"./tr":116,"./tr.js":116,"./tzl":117,"./tzl.js":117,"./tzm":118,"./tzm-latn":119,"./tzm-latn.js":119,"./tzm.js":118,"./ug-cn":120,"./ug-cn.js":120,"./uk":121,"./uk.js":121,"./ur":122,"./ur.js":122,"./uz":123,"./uz-latn":124,"./uz-latn.js":124,"./uz.js":123,"./vi":125,"./vi.js":125,"./x-pseudo":126,"./x-pseudo.js":126,"./yo":127,"./yo.js":127,"./zh-cn":128,"./zh-cn.js":128,"./zh-hk":129,"./zh-hk.js":129,"./zh-tw":130,"./zh-tw.js":130};function a(e){var t=i(e);return n(t)}function i(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=i,e.exports=a,a.id=135},function(e,t,n){"use strict";n.r(t),t.default=n.p+"css/app.css"},function(e,t,n){"use strict";n.r(t);n.p;var r=n(131),a=n.n(r),i=n(1),o=n.n(i),s=n(0),l=n.n(s);function c(e,t,n,r,a){function i(t){const n=Number(t)*e.pageSize,r=(Number(t)+1)*Number(e.pageSize);return e.table.filter(t=>t.name.includes(e.searchQuery)).slice(n,r)}a.reset(),r.reset("overview"),e.alertShow=!1,e.pypi_version="",e.dashboard_version="",e.isHits=!0,e.table=[],e.selectedItem=2,e.searchQuery="",e.pageSize="10",e.currentPage=0,e.toggleHits=function(){e.isHits=!e.isHits},t.get("api/overview").then((function(t){e.table=t.data})),e.getFilteredItems=function(){return i(e.currentPage)},e.canGoBack=function(){return e.currentPage>0},e.canGoForward=function(){return i(e.currentPage+1).length>0},e.nextPage=function(){e.currentPage++},e.previousPage=function(){e.currentPage--},e.go=function(e){n.path(e)},t.get("https://pypi.org/pypi/Flask-MonitoringDashboard/json").then((function(n){e.pypi_version=n.data.info.version,t.get("api/deploy_details").then((function(t){e.dashboard_version=t.data["dashboard-version"],e.alertShow=!function(e,t){let n=e.split("."),r=t.split(".");for(let e=0;e<3;e++){if(n[e]>r[e])return!1;if(n[e]<r[e])return!0}return!0}(e.pypi_version,e.dashboard_version)}))}))}function u(e,t,n,r,a,i,o,s){o.reset(),n.reset("hourly_load"),e.title="Hourly API Utilization",a.axesText="The X-axis represents the dates. The Y-axis presents the hours of the day.",a.contentText="The cell color represents the number of requests that the application received in a single hour. The darker the cell, the more requests it has processed. This information can be used to to discover the peak usage hours of the Flask application.",i.clear();let l=i.addDate("Start date");i.addDate("End date"),l.value.setDate(l.value.getDate()-14),i.setReload((function(){let e=i.getDate("Start date"),n=i.getDate("End date"),a=[...Array(24).keys()].map(e=>e+":00");t.get("api/hourly_load/"+e+"/"+n).then((function(e){let t=e.data.days,n=a,i=e.data.data,o=i.map((e,n)=>e.map((e,r)=>`Date: ${s("dateShort")(t[r])}<br>Time: ${n+":00"}<br>Requests: ${e}`));r.heatmap(t,n,i,{yaxis:{autorange:"reversed"},margin:{l:50}},o)}))})),i.reload()}function d(e,t,n,r,a,i,o){o.reset(),n.reset("multi_version"),e.title="Multi version API Utilization",a.axesText="The X-axis presents the versions that are used. The Y-axis presents theendpoints that are found in the Flask application.",a.contentText="The color of the cell presents the distribution of the amount of requests that the application received in a single version for a single endpoint. The darker the cell, the more requests a certain endpoint has processed in that version. Since it displays the distribution of the load, each column sums up to 100%. This information can be used to discover which endpoints process the most requests.",r.clear(),r.addVersions(),r.addEndpoints(),r.setReload((function(){let e=r.getMultiSelection("versions"),n=r.getMultiSelection("endpoints");t.post("api/multi_version",{data:{versions:e,endpoints:n}}).then((function(t){i.heatmap(e,n,t.data.map(e=>e.map(e=>0==e?"NaN":e)),{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category"}})}))}))}function f(e,t,n,r,a,i,o){o.reset(),n.reset("daily_load"),e.title="Daily API Utilization",a.axesText="The X-axis presents the amount of requests. The Y-axis presents a number of days.",a.contentText="This graph presents a horizontal stacked barplot. Each endpoint is represented by a color. In the legend on the right, you can disable a certain endpoint by clicking on it. You can also show in the information of a single endpoint by double clicking that endpoint in the legend. The information from this graph can be used to see on which days (a subset of) the endpoints are used the most.",r.clear();let s=r.addDate("Start date");s.value.setDate(s.value.getDate()-10),r.addDate("End date"),r.setReload((function(){let e=r.getDate("Start date"),n=r.getDate("End date");t.get("api/requests/"+e+"/"+n).then((function(e){let t=e.data.data.map(t=>({x:t.values,y:e.data.days,name:t.name,type:"bar",orientation:"h"}));i.chart(t,{barmode:"stack",xaxis:{title:"Number of requests"},yaxis:{type:"category",autorange:"reversed"}})}))})),r.reload()}function h(e,t,n,r,a,i,o){o.reset(),n.reset("api_performance"),e.title="API Performance",a.axesText="The X-axis presents the execution time in ms. The Y-axis presents every endpoint of the Flask application.",a.contentText="In this graph, it is easy to compare the execution times of different endpoints. This information can be used to discover which endpoints need to be improved in terms of response times.",r.clear(),r.addEndpoints(),r.setReload((function(){t.post("api/api_performance",{data:{endpoints:r.getMultiSelection("endpoints")}}).then((function(e){let t=e.data.map(e=>({x:e.values,type:"box",name:e.name}));i.chart(t,{xaxis:{title:"Execution time (ms)"},yaxis:{type:"category"}})}))}))}function p(e,t,n,r,a){function i(e,t){const n=moment().subtract(e,t).startOf(t),r=moment().subtract(e,t).endOf(t),a=moment().startOf(t),i=moment().endOf(t);return{comparison:{from:a.toDate(),to:i.toDate()},baseline:{from:n.toDate(),to:r.toDate()}}}r.reset(),n.reset("reporting"),e.reports={},e.activeSection="week",e.monthName=moment().format("MMMM"),e.previousMonthName=moment().subtract(1,"months").format("MMMM"),e.currentDay=moment().format("MMM DD"),e.yesterday=moment().subtract(1,"days").format("MMM DD"),e.currentWeekNumber=moment().isoWeek(),e.previousWeekNumber=moment().subtract(1,"weeks").isoWeek(),e.generating=!1,e.onlyShowInteresting=!0,e.activeSection="custom",e.intervals=i(1,"months"),e.versions=[],e.commitVersion=null,e.baseLineCommitVersion=null,e.selectSection=function(n){"commits"===n&&t.get("api/versions").then((function(t){e.versions=t.data})),e.activeSection=n;const r={day:[1,"days"],week:[1,"isoWeeks"],month:[1,"months"],custom:[1,"isoWeeks"]}[e.activeSection];e.intervals=i(r[0],r[1])},e.selectEntry=function(t,n){e.selectedSummary=t,e.selectedAnswer=n;const{comparison:r,baseline:i}=n.latencies_samples,o=[{name:`Comparison (N=${r.length})`,type:"violin",y:r},{name:`Baseline (N=${i.length})`,type:"violin",y:i}];a.chart(o,{yaxis:{title:"Execution time (ms)",rangemode:"nonnegative"}})},e.generateReport=function(){let n;e.generating=!0,e.error="",n="commits"===e.activeSection?t.post("api/reporting/make_report/commits",{commit_version:e.commitVersion,baseline_commit_version:e.baseLineCommitVersion}):t.post("api/reporting/make_report/intervals",{interval:{to:parseInt(""+e.intervals.comparison.to.getTime()/1e3),from:parseInt(""+e.intervals.comparison.from.getTime()/1e3)},baseline_interval:{to:parseInt(""+e.intervals.baseline.to.getTime()/1e3),from:parseInt(""+e.intervals.baseline.from.getTime()/1e3)}}),n.then(t=>{e.reports[e.activeSection]=t.data,e.generating=!1}),n.catch(t=>{e.error=t.data.message||"An unknown error occurred!",e.generating=!1})}}function m(e,t,n,r,a,i,o,s){r.reset(),n.reset("endpoint_hourly"),r.onNameChanged=function(t){e.title="Hourly API Utilization for "+t},a.axesText="The X-axis represents the dates. The Y-axis presents the hours of the day.",a.contentText="The cell color represents the number of requests that the application received in a single hour for this endpoint. The darker the cell, the more requests it has processed. This information can be used to discover the peak usage hours of this endpoint.",i.clear();let l=i.addDate("Start date");i.addDate("End date"),l.value.setDate(l.value.getDate()-14),i.setReload((function(){let e=i.getDate("Start date"),n=i.getDate("End date"),a=[...Array(24).keys()].map(e=>e+":00 ");t.get("api/hourly_load/"+e+"/"+n+"/"+r.info.id).then((function(e){let t=e.data.days,n=a,r=e.data.data,i=r.map((e,n)=>e.map((e,r)=>`Date: ${s("dateShort")(t[r])}<br>Time: ${n+":00"}<br>Requests: ${e}`));o.heatmap(t,n,r,{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category",autorange:"reversed"},margin:{l:50}},i)}))})),i.reload()}function g(e,t,n,r,a,i,o,s){r.reset(),a.reset("endpoint_user_version"),r.onNameChanged=function(t){e.title="User-Focused Multi-Version Performance for "+t},n.axesText='In this graph, the X-axis presents the versions that are used. The Y-axis presents (a subset of) all unique users, as specified by "dashboard.config.group_by". You can use the slider to select a subset of the all unique users.',n.contentText="The cell color represents the average response time (expressed in ms) of this endpoint per user per version.",i.clear(),i.addUsers(),i.addVersions(r.info.id),i.setReload((function(){t.post("api/version_user/"+r.info.id,{data:{versions:i.getMultiSelection("versions"),users:i.getMultiSelection("users")}}).then((function(e){let t=e.data.versions.map(e=>e.version+"<br>"+s("dateLayout")(e.date));o.heatmap(t,i.getMultiSelection("users"),e.data.data,{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category",title:"Users",autorange:"reversed"}})}))}))}function y(e,t,n,r,a,i,o){r.reset(),a.reset("endpoint_user"),r.onNameChanged=function(t){e.title="Per-User Performance for "+t},n.axesText="The X-axis presents the execution time in ms. The Y-axis presents the versions that are used.",n.contentText="This graph shows a horizontal boxplot for the versions that are used. With this graph you can found out whether the performance changes across different versions.",i.clear(),i.addUsers(),i.setReload((function(){t.post("api/endpoint_users/"+r.info.id,{data:{users:i.getMultiSelection("users")}}).then((function(e){o.chart(e.data.map(e=>({x:e.values,type:"box",name:e.user,marker:{color:e.color}})),{xaxis:{title:"Execution time (ms)"},yaxis:{type:"category",autorange:"reversed"},margin:{l:200}})}))}))}function _(e,t,n,r,a,i){r.reset(),r.onNameChanged=function(t){e.title="Profiler for "+t},n.reset("endpoint_profiler"),a.init("requests"),t.get("api/num_profiled/"+r.info.id).then((function(e){a.setTotal(e.data)})),a.onReload=function(){i.isLoading=!0,t.get("api/profiler_table/"+r.info.id+"/"+a.getLeft()+"/"+a.perPage).then((function(t){e.table=t.data,i.isLoading=!1;for(let t of e.table){let e=t.stack_lines;for(let t of e)t.min=0===parseInt(t.indent),t.showRow=parseInt(t.indent)<2,t.body=o(e,parseInt(t.position))}}))},e.buttonText=function(e){return e.stack_lines.every(e=>e.showRow)?"Hide all":"Expand all"},e.toggleButton=function(e){if(e.stack_lines.every(e=>e.showRow))for(let t of e.stack_lines)t.min=0===parseInt(t.indent),t.showRow=parseInt(t.indent)<2;else for(let t of e.stack_lines)t.showRow=!0,t.min=!0},e.toggleRows=function(e,t){if(t.min)for(let n of t.body)e.stack_lines[n].min=!1,e.stack_lines[n].showRow=!1;else for(let n of t.body)e.stack_lines[n].showRow=parseInt(e.stack_lines[n].indent)===parseInt(t.indent)+1;t.min=!t.min};let o=function(e,t){let n=[],r=t+1;for(;r<e.length&&parseInt(e[r].indent)>parseInt(e[t].indent);)n.push(r),r+=1;return n};e.computeColor=function(e){let t=[230,74,54],n=[198,220,0];return"rgb("+(t[0]*e+n[0]*(1-e))+", "+(t[1]*e+n[1]*(1-e))+", "+(t[2]*e+n[2]*(1-e))+")"}}function v(e,t,n,r,a){r.reset(),e.table=[],r.onNameChanged=function(t){e.title="Grouped profiler for "+t},n.reset("endpoint_grouped_profiler"),t.get("api/grouped_profiler/"+r.info.id).then((function(t){a.isLoading=!1,e.table=t.data;for(let t=0;t<e.table.length;t++){let n=e.table[t];n.min=0===parseInt(n.indent),n.showRow=parseInt(n.indent)<2,n.body=o(e.table,t)}let n=i(e.table,0);const r=d3.scaleOrdinal(d3.schemeCategory20);Sunburst().data(n).label("name").size("size").color((e,t)=>r(t?t.data.name:null)).tooltipContent((e,t)=>"Size: <i>"+t.value+"</i>")(document.getElementById("sunburst"))}));let i=function(t,n){if(0===n){let n=0;for(;n+1<t.length&&0===parseInt(t[n+1].indent);)n++;return{name:t[n].code,children:i(t[n].body.map(t=>e.table[t]),1)}}{let r=[];for(let a of t)parseInt(a.indent)===n&&(a.body.length>0?r.push({name:a.code,children:i(a.body.map(t=>e.table[t]),n+1)}):r.push({name:a.code,size:Math.max(a.duration,1)}));return r}};e.buttonText=function(){return e.table.every(e=>e.showRow)?"Hide all":"Expand all"},e.toggleButton=function(){if(e.table.every(e=>e.showRow))for(let t of e.table)t.min=0===parseInt(t.indent),t.showRow=parseInt(t.indent)<2;else for(let t of e.table)t.showRow=!0,t.min=!0},e.toggleRows=function(t){if(t.min)for(let n of t.body)e.table[n].min=!1,e.table[n].showRow=!1;else for(let n of t.body)e.table[n].showRow=parseInt(e.table[n].indent)===parseInt(t.indent)+1;t.min=!t.min};let o=function(e,t){let n=[],r=t+1;for(;r<e.length&&parseInt(e[r].indent)>parseInt(e[t].indent);)n.push(r),r+=1;return n};e.computeColor=function(e){let t=[230,74,54],n=[198,220,0];return"rgb("+(t[0]*e+n[0]*(1-e))+", "+(t[1]*e+n[1]*(1-e))+", "+(t[2]*e+n[2]*(1-e))+")"}}function x(e,t,n,r,a,i){e.table=[],n.reset(),r.reset("endpoint_outlier"),n.onNameChanged=function(t){e.title="Outliers for "+t},a.init("outliers"),t.get("api/num_outliers/"+n.info.id).then((function(e){a.setTotal(e.data)})),a.onReload=function(){t.get("api/outlier_table/"+n.info.id+"/"+a.getLeft()+"/"+a.perPage).then((function(t){e.table=t.data}))},t.get("api/outlier_graph/"+n.info.id).then((function(e){i.chart(e.data.map(e=>({x:e.values,type:"box",name:e.name,marker:{color:e.color}})),{xaxis:{title:"CPU loads (%)"},yaxis:{type:"category",autorange:"reversed"}})}))}function b(e,t,n,r,a,i,o){a.reset("status_code_distribution"),r.reset(),i.setReload((function(){const n=r.info.id;t.get("api/endpoint_status_code_summary/"+n).then((function(t){const n=t.data.distribution,r=Object.keys(n),a=[{values:r.map(e=>n[e]),labels:r,type:"pie"}];e.error_requests=t.data.error_requests,o.chart(a,{height:400,width:500})}))})),i.reload()}function M(e,t,n,r,a,i,o){r.reset(),a.reset("custom_graph"+r.graphId),e.title=r.getGraphTitle(),r.onNameChanged=function(t){e.title=t},n.axesText="",n.contentText="",i.clear();let s=i.addDate("Start date");s.value.setDate(s.value.getDate()-14),i.addDate("End date"),i.setReload((function(){let n=i.getDate("Start date"),a=i.getDate("End date");t.get("api/custom_graph/"+r.graphId+"/"+n+"/"+a).then((function(t){let n=t.data.map(e=>e.value),r=t.data.map(e=>e.time);o.chart([{x:r,y:n,type:"bar",name:e.title}],{yaxis:{title:"Values"},margin:{l:100}})}))})),i.reload()}const w={headers:{"Content-Type":"application/x-www-form-urlencoded;charset=utf-8;"}};function k(e,t,n,r,a){function i(){t.get("api/users").then((function(t){e.userData=t.data}))}r.reset(),n.reset("configuration"),a.setConfirm("delete",()=>{return n=e.user,void t.post("api/user/delete",$.param({user_id:n.id}),w).then((function(e){i(),$("#deleteModal").modal("hide"),a.setErrorMessage("delete",null)}),(function(e){a.setErrorMessage("delete",e.data.message)}));var n}),a.setConfirm("edit",()=>(e.user,void t.post("api/user/edit",$.param({user_id:e.user.id,old_password:$("#edit-old-pwd")[0].value,new_password:$("#edit-new-pwd")[0].value,new_password2:$("#edit-new-pwd2")[0].value,is_admin:$("#edit-admin")[0].checked}),w).then((function(e){i(),$("#editModal").modal("hide"),a.setErrorMessage("edit",null)}),(function(e){a.setErrorMessage("edit",e.data.message)})))),a.setConfirm("create",(function(){t.post("api/user/create",$.param({username:$("#create-username")[0].value,password:$("#create-pwd")[0].value,password2:$("#create-pwd2")[0].value,is_admin:$("#create-admin")[0].checked}),w).then((function(e){i(),$("#createModal").modal("hide"),a.setErrorMessage("create",null)}),(function(e){a.setErrorMessage("create",e.data.message)}))})),e.details={},e.config={},e.error={},e.userData=[],t.get("api/users").then((function(t){e.userData=t.data})),t.get("api/deploy_details").then((function(t){e.details=t.data})),t.get("api/deploy_config").then((function(t){e.config=t.data})),e.openModal=function(t,n){e.user=n,$(`#${t}Modal`).modal()}}function T(e,t,n,r,a,i,o,s){r.reset(),a.reset("endpoint_ip"),r.onNameChanged=function(t){e.title="IP-Focused Multi-Version Performance for "+t},n.axesText="In this graph, the X-axis presents the versions that are used. The Y-axis presents (a subset of) all IP-addresses. You can use the slider to select a subset of the all IP-addresses.",n.contentText="The cell color represents the average response time (expressed in ms) of this endpoint per IP per version.",i.clear(),i.addIP(),i.addVersions(r.info.id),i.setReload((function(){t.post("api/version_ip/"+r.info.id,{data:{versions:i.getMultiSelection("versions"),ip:i.getMultiSelection("IP-addresses")}}).then((function(e){let t=e.data.versions.map(e=>e.version+"<br>"+s("dateLayout")(e.date));o.heatmap(t,i.getMultiSelection("IP-addresses"),e.data.data,{xaxis:{type:"category",title:"Versions"},yaxis:{type:"category",title:"IP-addresses"}})}))}))}function L(e,t,n,r,a,i,o,s){r.reset(),a.reset("endpoint_version"),r.onNameChanged=function(t){e.title="Per-Version Performance for "+t},n.axesText="The X-axis presents the execution time in ms. The Y-axis presents the versions that are used.",n.contentText="This graph shows a horizontal boxplot for the versions that are used. With this graph you can found out whether the performance changes across different versions.",i.clear(),i.addVersions(r.info.id),i.setReload((function(){t.post("api/endpoint_versions/"+r.info.id,{data:{versions:i.getMultiSelection("versions")}}).then((function(e){o.chart(e.data.map(e=>({x:e.values,type:"box",name:e.version+"<br>"+s("dateLayout")(e.date),marker:{color:e.color}})),{xaxis:{title:"Execution time (ms)"},yaxis:{type:"category",autorange:"reversed"},margin:{l:200}})}))}))}var D=function(e,t){this.page="",this.endpoint=t,this.reset=function(e){this.page!==e&&(this.page=e),"custom_graph"===e.substr(0,"custom_graph".length)?$("#collapseCustomGraphs").collapse("show"):$("#collapseCustomGraphs").collapse("hide");["overview","hourly_load","multi_version","daily_load","api_performance","reporting"].includes(e)?$("#collapseDashboard").collapse("show"):$("#collapseDashboard").collapse("hide");["endpoint_hourly","endpoint_user_version","endpoint_ip","endpoint_version","endpoint_user","endpoint_profiler","endpoint_grouped_profiler","endpoint_outlier","status_code_distribution"].includes(e)?$("#collapseEndpoint").collapse("show"):$("#collapseEndpoint").collapse("hide")}};window.Plotly=a.a,window.$=window.jQuery=o.a,n(133),window.moment=l.a;let A=angular.module("fmdApp",["ngRoute"]);!function(e){e.filter("duration_ms",(function(){return function(e){return Math.round(10*parseFloat(e))/10}})),e.filter("duration",(function(){return function(e){let t=Math.round(10*parseFloat(e))/10,n=t/1e3,r=Math.floor(n/60),a=Math.floor(n/3600),i=Math.floor(a/24),o="";return t<100.5?o=t+" ms":t<999.5?o=Math.round(t)+" ms":n<60?(n=Math.round(t/100)/10,o=n+" sec"):0===a?(n=Math.round(n%60),o=r+" min",n>0&&(o+=", "+n+" sec")):0===i?(o=a+" hr",r=Math.round(r%60),r>0&&(o+=", "+r+" min")):(o=i+" d",a=Math.round(a%24),a>0&&(o+=", "+a+" hr")),o}})),e.filter("dateLayout",(function(){return e=>{let t=new Date(e);return("0"+t.getDate()).slice(-2)+"-"+("0"+(t.getMonth()+1)).slice(-2)+"-"+t.getFullYear()+" "+("0"+t.getHours()).slice(-2)+":"+("0"+t.getMinutes()).slice(-2)}})),e.filter("dateShort",(function(){return e=>{let t=new Date(e),n=t.getDate(),r=t.getMonth(),a=t.getFullYear();return["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][r]+" "+n+", "+a}})),e.filter("dateDifference",(function(){return function(e){if(null===e)return"";let t=(new Date).getTime()-Date.parse(e),n=Math.round(t/1e3),r=Math.round(n/60),a=Math.round(r/60),i=Math.round(a/24),o=Math.round(i/7),s=Math.round(i/30),l=Math.round(i/365);function c(e){return 1!==e?"s":""}return n<60?n+" second"+c(n)+" ago":r<60?r+" minute"+c(r)+" ago":a<24?a+" hour"+c(a)+" ago":i<7?i+" day"+c(i)+" ago":o<5?o+" week"+c(o)+" ago":s<12?s+" month"+c(s)+" ago":l+" year"+c(l)+" ago"}})),e.filter("abs",(function(){return function(e){return Math.abs(e)}}))}(A),function(e){e.directive("pagination",(function(){return{templateUrl:"static/elements/pagination.html",controller:"PaginationController"}})),e.directive("menu",(function(){return{templateUrl:"static/elements/menu.html",controller:"MenuController"}})),e.directive("monitorlevel",(function(){return{templateUrl:"static/elements/monitorLevel.html",controller:"MonitorLevelController",scope:{name:"=",value:"="}}})),e.directive("endpointdetails",(function(){return{templateUrl:"static/elements/endpointDetails.html",controller:"EndpointController"}})),e.directive("modal",(function(){return{transclude:!0,templateUrl:"static/elements/modal.html",controller:"ModalController",scope:{name:"=",title:"=",yes:"=?",no:"=?"}}}))}(A),A.service("formService",["$http","endpointService","$filter",function(e,t,n){let r=this;function a(e){let t={name:e,values:[],selected:[],initialized:!1};return r.multiFields.push(t),t}this.dateFields=[],this.multiFields=[],this.isLoading=!0,this.clear=function(){r.multiFields=[],r.dateFields=[]},this.initialize=function(e){e.initialized=!0,r.multiFields.every(e=>e.initialized)&&r.reload()},this.getMultiSelection=function(e){return r.multiFields.find(t=>t.name==e).selected.map(e=>e.id)},this.addDate=function(e){let t={name:e,value:new Date};return r.dateFields.push(t),t},this.getDate=function(e){return i(r.dateFields.find(t=>t.name==e).value)},this.addVersions=function(t){let i=a("versions"),o="api/versions";void 0!==t&&(o+="/"+t),e.get(o).then((function(e){i.values=e.data.map(e=>({id:e.version,text:e.version+" : "+n("dateLayout")(e.date)})),i.selected=i.values.slice(-10),r.initialize(i)}))},this.addEndpoints=function(){let t=a("endpoints");e.get("api/endpoints_hits").then((function(e){t.values=e.data.map(e=>({id:e.name,text:e.name+" : "+e.hits+" requests"})),t.selected=t.values.slice(0,10),r.initialize(t)}))},this.addUsers=function(){let n=a("users");e.get("api/users/"+t.info.id).then((function(e){n.values=e.data.map(e=>({id:e.user,text:e.user+" : "+e.hits+" requests"})),n.selected=n.values.slice(0,10),r.initialize(n)}))},this.addIP=function(){let n=a("IP-addresses");e.get("api/ip/"+t.info.id).then((function(e){n.values=e.data.map(e=>({id:e.ip,text:e.ip+" : "+e.hits+" requests"})),n.selected=n.values.slice(0,10),r.initialize(n)}))};let i=function(e){return e.getFullYear()+"-"+("0"+(e.getMonth()+1)).slice(-2)+"-"+("0"+e.getDate()).slice(-2)};this.reload=function(){},this.setReload=function(e){this.reload=function(){r.isLoading=!0,e()}}}]),A.service("infoService",(function(){this.graphText="You can hover the graph with your mouse to see the actual values. You can also use the buttons at the top of the graph to select a subset of graph, scale it accordingly, or save the graph as a PNG image.",this.axesText="",this.contentText=""})),A.service("endpointService",["$http","$routeParams",function(e,t){let n=this;this.info={id:0,endpoint:""},this.graphId=0,this.customGraphs=[],this.getGraph=function(){return this.customGraphs.find(e=>e.graph_id===n.graphId)},this.getGraphTitle=function(){let e=this.getGraph();return void 0!==e?e.title:""},e.get("api/custom_graphs").then((function(e){n.customGraphs=e.data,0!==n.graphId&&n.onNameChanged(n.getGraphTitle())})),this.reset=function(){void 0!==t.endpointId?(this.info.id=t.endpointId,this.getInfo()):void 0!==t.graphId?this.graphId=t.graphId:this.info.id=0},this.onNameChanged=function(e){},this.getInfo=function(){e.get("api/endpoint_info/"+this.info.id).then((function(e){n.info=e.data,n.onNameChanged(n.info.endpoint)}))}}]),A.service("menuService",["$http","endpointService",D]),A.service("paginationService",["$http","endpointService",D]),A.service("paginationService",(function(){this.init=function(e){this.page=1,this.perPage=5,this.total=0,this.name=e},this.maxPages=function(){return Math.ceil(this.total/this.perPage)},this.onReload=function(){},this.getLeft=function(){return(this.page-1)*this.perPage},this.getRight=function(){return Math.min(this.total,this.getLeft()+this.perPage)},this.getFirstPage=function(){let e=this.getPages();return e.length>0?e[0]:this.page},this.getLastPage=function(){let e=this.getPages();return e.length>0?e[e.length-1]:this.page},this.goto=function(e){this.page=e,this.onReload()},this.setTotal=function(e){this.total=e,this.onReload()},this.getPages=function(){let e=this.page-1,t=this.page+1,n=[];e<=0&&(t-=e-1,e=1),t>this.maxPages()&&(t=this.maxPages()),2==e?n.push(1):3==e?n.push(1,2):e>3&&n.push(1,"...");for(let r=e;r<=t;r++)n.push(r);return this.maxPages()-t>2?n.push("...",this.maxPages()):this.maxPages()-t==2?n.push(this.maxPages()-1,this.maxPages()):this.maxPages()-t==1&&n.push(this.maxPages()),n}})),A.service("plotlyService",["formService",function(e){let t={height:600,margin:{l:200}},n={displaylogo:!1,responsive:!0};this.heatmap=function(e,n,r,a,i){this.chart([{x:e,y:n,z:r.map(e=>e.map(e=>0===e?NaN:e)),colorscale:"YIOrRd",reversescale:!0,type:"heatmap",text:i,hoverinfo:void 0===i?void 0:"text"}],$.extend({},t,a))},this.chart=function(r,a){e.isLoading=!1,Plotly.newPlot("chart",r,$.extend({},t,a),n)}}]),A.service("modalService",(function(){this.action={},this.error={},this.setConfirm=function(e,t){this.action[e]=t},this.setErrorMessage=function(e,t){this.error[e]=t},this.confirm=function(e){this.action[e]()}})),A.controller("MonitorLevelController",["$scope","$http",function(e,t){e.sendForm=function(n){e.value=n,t.post("api/set_rule",$.param({name:e.name,value:n}),{headers:{"Content-Type":"application/x-www-form-urlencoded;charset=utf-8;"}})},e.computeColor=function(t){let n=.2;e.value===t&&(n=1);let r=[230,74,54],a=[237,255,77],i=t/3;return"rgba("+(r[0]*i+a[0]*(1-i))+", "+(r[1]*i+a[1]*(1-i))+", "+(r[2]*i+a[2]*(1-i))+", "+n+")"}}]),A.controller("MenuController",["$scope","menuService",function(e,t){e.menu=t}]),A.controller("InfoController",["$scope","infoService",function(e,t){e.info=t}]),A.controller("FormController",["$scope","formService",function(e,t){e.handler=t}]),A.controller("EndpointController",["$scope","endpointService",function(e,t){e.endpoint=t}]),A.controller("PaginationController",["$scope","paginationService",function(e,t){e.pagination=t}]),A.controller("ModalController",["$scope","$window","$browser","modalService",function(e,t,n,r){r.setConfirm("logout",(function(){t.location.href=n.baseHref()+"logout"})),e.modal=r}]),A.config(["$locationProvider","$routeProvider",function(e,t){t.when("/overview",{templateUrl:"static/pages/overview.html",controller:["$scope","$http","$location","menuService","endpointService",c]}).when("/hourly_load",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","plotlyService","infoService","formService","endpointService","$filter",u]}).when("/multi_version",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","formService","infoService","plotlyService","endpointService",d]}).when("/daily_utilization",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","formService","infoService","plotlyService","endpointService",f]}).when("/api_performance",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","formService","infoService","plotlyService","endpointService",h]}).when("/reporting",{templateUrl:"static/pages/reporting.html",controller:["$scope","$http","menuService","endpointService","plotlyService",p]}).when("/endpoint/:endpointId/hourly_load",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","menuService","endpointService","infoService","formService","plotlyService","$filter",m]}).when("/endpoint/:endpointId/version_user",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService","$filter",g]}).when("/endpoint/:endpointId/version_ip",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService","$filter",T]}).when("/endpoint/:endpointId/versions",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService","$filter",L]}).when("/endpoint/:endpointId/users",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService",y]}).when("/endpoint/:endpointId/profiler",{templateUrl:"static/pages/profiler.html",controller:["$scope","$http","menuService","endpointService","paginationService","formService",_]}).when("/endpoint/:endpointId/grouped-profiler",{templateUrl:"static/pages/grouped_profiler.html",controller:["$scope","$http","menuService","endpointService","formService",v]}).when("/endpoint/:endpointId/outliers",{templateUrl:"static/pages/outliers.html",controller:["$scope","$http","endpointService","menuService","paginationService","plotlyService",x]}).when("/endpoint/:endpointId/status_code_distribution",{templateUrl:"static/pages/status_code_distribution.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService",b]}).when("/custom_graph/:graphId",{templateUrl:"static/pages/plotly_graph.html",controller:["$scope","$http","infoService","endpointService","menuService","formService","plotlyService",M]}).when("/configuration",{templateUrl:"static/pages/configuration.html",controller:["$scope","$http","menuService","endpointService","modalService",k]}).otherwise({redirectTo:"/overview"}),e.html5Mode({enabled:!0,requireBase:!0})}]),o()("#sidenavToggler").click((function(e){e.preventDefault(),o()("body").toggleClass("sidenav-toggled"),o()(".navbar-sidenav .nav-link-collapse").addClass("collapsed"),o()(".navbar-sidenav .sidenav-second-level, .navbar-sidenav .sidenav-third-level").removeClass("show")})),o()(".navbar-sidenav .nav-link-collapse").click((function(e){e.preventDefault(),o()("body").removeClass("sidenav-toggled")})),window.app=A}]);
diff --git a/flask_monitoringdashboard/static/pages/overview.html b/flask_monitoringdashboard/static/pages/overview.html
index fd694fd06..7551c1cdb 100644
--- a/flask_monitoringdashboard/static/pages/overview.html
+++ b/flask_monitoringdashboard/static/pages/overview.html
@@ -31,7 +31,7 @@
             </ul>
 
             <div class="row" style="margin-bottom: 7px">
-                <div class="col-md-6 col-sm-12">
+                <div class="col-md-3 col-sm-12">
                     Show
                     <select style="width: 60px; display: inline-block;"
                             class='form-control form-control-sm' name="ddwa"
@@ -44,7 +44,18 @@
                     entries
                 </div>
 
-                <div class="col-md-6 col-sm-12" style="text-align: right">
+                <div class="col-md-6 col-sm-12">
+                    Blueprint:
+                    <select style='width: 180px; display: inline-block;' ng-model="slectedBlueprint"
+                            class="form-control form-control-sm">
+                        <option ng-repeat="blueprint in blueprints track by $index"
+                                value="{{ blueprint }}">
+                            {{ blueprint }}
+                        </option>
+                    </select>
+                </div>
+
+                <div class="col-md-3 col-sm-12" style="text-align: right">
                     Search:
                     <input ng-model="searchQuery"
                            style="display: inline-block; width: 180px"
@@ -54,7 +65,7 @@
 
             <div class="row">
                 <div class="col-md-12">
-                    <table class="table table-hover table-bordered">
+                    <table class="table table-hover table-bordered table-sm">
                         <thead>
                         <tr>
                             <th></th>
@@ -76,23 +87,15 @@
                             ng-click="go('/endpoint/' + row.id + '/hourly_load')">
 
                             <td style="background-color: {{ row.color }}"></td>
-                            <td style="max-width: 200px;">{{ row.name }}</td>
-
-
-                            <td class="table_cell_with_error_count"
+                            <td class="align-middle">{{ row.name }}</td>
+                            <td class="table_cell_with_error_count align-middle"
                                 ng-show="isHits"
                                 style="text-align: right;"
                                 ng-attr-error-count="
-
-
-
-
                                         {{ (row['hits-today-errors'] > 0) ? row['hits-today-errors'] : ''}}">
                                 {{ row['hits-today'] | number }}
                             </td>
-
-
-                            <td class="table_cell_with_error_count"
+                            <td class="table_cell_with_error_count align-middle"
                                 ng-show="isHits" style="text-align: right;"
                                 ng-attr-error-count="
 
@@ -103,17 +106,17 @@
                                 {{ row['hits-week'] | number }}
                             </td>
 
-                            <td ng-show="isHits" style="text-align: right;">
+                            <td ng-show="isHits" style="text-align: right;" class="align-middle">
                                 {{ row['hits-overall'] | number }}
                             </td>
 
-                            <td ng-show="isHits==false"
+                            <td ng-show="isHits==false" class="align-middle"
                                 style="text-align: right;">{{ row['median-today'] | duration_ms }}</td>
-                            <td ng-show="isHits==false"
+                            <td ng-show="isHits==false" class="align-middle"
                                 style="text-align: right;">{{ row['median-week'] | duration_ms }}</td>
-                            <td ng-show="isHits==false"
+                            <td ng-show="isHits==false" class="align-middle"
                                 style="text-align: right;">{{ row['median-overall'] | duration_ms }}</td>
-                            <td style="text-align: center;">{{ row['last-accessed'] | dateDifference }}</td>
+                            <td style="text-align: center;" class="align-middle">{{ row['last-accessed'] | dateDifference }}</td>
                             <td ng-click="$event.stopPropagation()">
                                 <monitorlevel name="row.name"
                                               value="row.monitor"></monitorlevel>
diff --git a/flask_monitoringdashboard/templates/fmd_base.html b/flask_monitoringdashboard/templates/fmd_base.html
index 6b31739b5..90e8d0ed4 100644
--- a/flask_monitoringdashboard/templates/fmd_base.html
+++ b/flask_monitoringdashboard/templates/fmd_base.html
@@ -1,76 +1,89 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en" ng-app="fmdApp">
-<head>
-    <title>Flask-MonitoringDashboard</title>
-    <base href="{{ url_for(blueprint_name + '.index') }}">
-    <meta charset="utf-8">
+  <head>
+    <title>{{ title_name }}</title>
+    <base href="{{ url_for(blueprint_name + '.index') }}" />
+    <meta charset="utf-8" />
 
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta
+      name="viewport"
+      content="width=device-width, initial-scale=1, shrink-to-fit=no"
+    />
 
-    <link rel="stylesheet"
-          href="{{ url_for(blueprint_name + '.static', filename='css/app.css') }}"/>
+    <link
+      rel="stylesheet"
+      href="{{ url_for(blueprint_name + '.static', filename='css/app.css') }}"
+    />
 
-    <link rel="shortcut icon"
-          href="{{ url_for(blueprint_name + '.static', filename='img/favicon.ico') }}"/>
-</head>
+    <link
+      rel="shortcut icon"
+      href="{{ url_for(blueprint_name + '.static', filename='img/favicon.ico') }}"
+    />
+  </head>
 
-{% block body %}
-    <body class="fixed-nav sticky-footer bg-dark" id="page-top">
-    <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top" id="mainNav">
-        <div class="navbar-brand brand-plain">
-            <a href="overview"><h4>Flask Monitoring Dashboard</h4></a>
-        </div>
+  {% block body %}
+  <body class="fixed-nav sticky-footer bg-dark" id="page-top">
+    <nav
+      class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top"
+      id="mainNav"
+    >
+      <div class="navbar-brand brand-plain">
+        <a href="overview"><h4>{{ brand_name }}</h4></a>
+      </div>
 
-        <div class="collapse navbar-collapse" id="navbarResponsive">
-            <menu></menu>
-            <ul class="navbar-nav sidenav-toggler">
-                <li class="nav-item">
-                    <a class="nav-link text-center" id="sidenavToggler">
-                        <i class="fa fa-fw fa-angle-left"></i>
-                    </a>
-                </li>
-            </ul>
-            <ul class="navbar-nav ml-auto">
-                <li class="nav-item">
-                 <span style="color: #adb5bd;">
-                     Automatically monitor the evolving performance of Flask/Python web services
-                 </span>
-                </li>
-            </ul>
-            <ul class="navbar-nav ml-auto">
-                <li class="nav-item">
-                    <a class="nav-link" data-toggle="modal" data-target="#logoutModal">
-                        <i class="fas fa-sign-out-alt"></i>Logout</a>
-                </li>
-            </ul>
-        </div>
+      <div class="collapse navbar-collapse" id="navbarResponsive">
+        <menu></menu>
+        <ul class="navbar-nav sidenav-toggler">
+          <li class="nav-item">
+            <a class="nav-link text-center" id="sidenavToggler">
+              <i class="fa fa-fw fa-angle-left"></i>
+            </a>
+          </li>
+        </ul>
+        <ul class="navbar-nav ml-auto">
+          <li class="nav-item">
+            <span style="color: #adb5bd"> {{ description }} </span>
+          </li>
+        </ul>
+        <ul class="navbar-nav ml-auto">
+          <li class="nav-item">
+            <a class="nav-link" data-toggle="modal" data-target="#logoutModal">
+              <i class="fas fa-sign-out-alt"></i>Logout</a
+            >
+          </li>
+        </ul>
+      </div>
     </nav>
 
     <div class="content-wrapper">
-        <div class="container page">
-            <div id="content" class="main" ng-view></div>
+      <div class="container page">
+        <div id="content" class="main" ng-view></div>
+      </div>
+      <footer class="sticky-footer">
+        <div class="container">
+          <div class="text-center">
+            Click
+            <a
+              target="_blank"
+              href="http://flask-monitoringdashboard.readthedocs.io"
+              >here</a
+            >
+            to read advanced documentation.
+          </div>
         </div>
-        <footer class="sticky-footer">
-            <div class="container">
-                <div class="text-center">
-                    Click <a target="_blank"
-                             href="http://flask-monitoringdashboard.readthedocs.io">here</a>
-                    to read advanced documentation.
-                </div>
-            </div>
-        </footer>
+      </footer>
 
-        <modal name="'logout'" title="'Logout?'">
-            <p>Are you sure you want to logout?</p>
-        </modal>
+      <modal name="'logout'" title="'Logout?'">
+        <p>Are you sure you want to logout?</p>
+      </modal>
     </div>
-{% endblock %}
+    {% endblock %}
 
-<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>
-<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular-route.js"></script>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>
-<script src="https://unpkg.com/sunburst-chart"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>
+    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular-route.js"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>
+    <script src="https://unpkg.com/sunburst-chart"></script>
 
-<script src="{{ url_for(blueprint_name + '.static', filename='js/app.js') }}"></script>
-</body>
-</html>
\ No newline at end of file
+    <script src="{{ url_for(blueprint_name + '.static', filename='js/app.js') }}"></script>
+  </body>
+</html>
diff --git a/flask_monitoringdashboard/templates/fmd_login.html b/flask_monitoringdashboard/templates/fmd_login.html
index 960676d99..c9fd9464a 100644
--- a/flask_monitoringdashboard/templates/fmd_login.html
+++ b/flask_monitoringdashboard/templates/fmd_login.html
@@ -1,54 +1,81 @@
-{% extends "fmd_base.html" %}
-{% block body %}
+{% extends "fmd_base.html" %} {% block body %}
 
 <body>
-    <div class="container py-5">
-        <div class="row">
-            <div class="col-md-8 offset-md-2">
-
-                <div class="text-center" style="margin-bottom: 20px; margin-top: -30px;">
-                    <div style="text-align: center;">
-                        <img src="{{ url_for(blueprint_name + '.static', filename='img/header.png') }}" width="80%" />
-                    </div>
-                    <span>Automatically monitor the evolving performance of Flask/Python web services</span>
-                </div>
-            </div>
+  <div class="container py-5">
+    {% if show_login_banner %}
+    <div class="row">
+      <div class="col-md-8 offset-md-2">
+        <div class="text-center" style="margin-bottom: 20px; margin-top: -30px">
+          <div style="text-align: center">
+            <img
+              src="{{ url_for(blueprint_name + '.static', filename='img/header.png') }}"
+              width="80%"
+            />
+          </div>
+          <span
+            >Automatically monitor the evolving performance of Flask/Python web
+            services</span
+          >
         </div>
+      </div>
+    </div>
+    {% endif %}
 
-        <div class="row">
-            <div class="col-md-4 offset-md-4">
-                <span class="anchor" id="formLogin"></span>
-                <div class="card card-outline-secondary">
-                    <div class="card-header">
-                        <h5>Login</h5>
-                    </div>
-
-                    <div class="card-body">
-                        <form class="form" method="POST" action="login">
-                            <div class="form-group">
-                                <label for="formName"><i class="fa fa-user"></i> Login</label>
-                                <input id="formName" name="name" type="text" class="form-control" placeholder="Username"
-                                    autofocus required />
-                            </div>
+    <div class="row">
+      <div class="col-md-4 offset-md-4">
+        <span class="anchor" id="formLogin"></span>
+        <div class="card card-outline-secondary">
+          <div class="card-header">
+            <h5>Login</h5>
+          </div>
 
-                            <div class="form-group">
-                                <label for="formPassword"><i class="fa fa-lock"></i> Password</label>
-                                <input name="password" type="password" class="form-control" placeholder="Password"
-                                    required />
-                            </div>
+          <div class="card-body">
+            <form class="form" method="POST" action="login">
+              <div class="form-group">
+                <label for="formName"><i class="fa fa-user"></i> Login</label>
+                <input
+                  id="formName"
+                  name="name"
+                  type="text"
+                  class="form-control"
+                  placeholder="Username"
+                  autofocus
+                  required
+                />
+              </div>
 
-                            <button name="Login" class="btn btn-primary btn-block">Login</button>
-                        </form>
-                        <hr />
+              <div class="form-group">
+                <label for="formPassword"
+                  ><i class="fa fa-lock"></i> Password</label
+                >
+                <input
+                  name="password"
+                  type="password"
+                  class="form-control"
+                  placeholder="Password"
+                  required
+                />
+              </div>
 
-                        <div class="text-center">
-                            For advanced documentation, see
-                            <a target="_blank" href="http://flask-monitoringdashboard.readthedocs.io">this site</a>
-                        </div>
-                    </div>
-                </div>
+              <button name="Login" class="btn btn-primary btn-block">
+                Login
+              </button>
+            </form>
+            <hr />
+            {% if show_login_footer %}
+            <div class="text-center">
+              For advanced documentation, see
+              <a
+                target="_blank"
+                href="http://flask-monitoringdashboard.readthedocs.io"
+                >this site</a
+              >
             </div>
+            {% endif %}
+          </div>
         </div>
+      </div>
     </div>
+  </div>
 </body>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/flask_monitoringdashboard/views/__init__.py b/flask_monitoringdashboard/views/__init__.py
index 53289b2e2..78c1cfff0 100644
--- a/flask_monitoringdashboard/views/__init__.py
+++ b/flask_monitoringdashboard/views/__init__.py
@@ -23,4 +23,9 @@ def static(filename):
 @blueprint.route('/<path:path>')  # Catch-All URL: http://flask.pocoo.org/snippets/57/
 @secure
 def index(path):
-    return render_template('fmd_base.html', blueprint_name=config.blueprint_name)
+    return render_template('fmd_base.html', 
+        blueprint_name=config.blueprint_name, 
+        brand_name=config.brand_name, 
+        title_name=config.title_name,
+        description=config.description,
+    )
diff --git a/flask_monitoringdashboard/views/auth.py b/flask_monitoringdashboard/views/auth.py
index 46c487a3e..96b2b2e23 100644
--- a/flask_monitoringdashboard/views/auth.py
+++ b/flask_monitoringdashboard/views/auth.py
@@ -30,7 +30,11 @@ def login():
         if user is not None:
             on_login(user=user)
             return redirect(url_for(MAIN_PAGE))
-    return render_template('fmd_login.html', blueprint_name=config.blueprint_name)
+    return render_template('fmd_login.html', 
+        blueprint_name=config.blueprint_name, 
+        show_login_banner=config.show_login_banner, 
+        show_login_footer=config.show_login_footer,
+    )
 
 
 @blueprint.route('/logout')
diff --git a/requirements-micro.txt b/requirements-micro.txt
new file mode 100644
index 000000000..553032c3b
--- /dev/null
+++ b/requirements-micro.txt
@@ -0,0 +1,10 @@
+click
+apscheduler
+flask>=0.9            # for monitoring the web-service
+sqlalchemy>=1.1.9     # for database support
+configparser          # for parsing the config-file
+psutil                # for logging extra CPU-info
+colorhash             # for hashing a string into a color
+numpy                 # for computing median and other stats
+pytz                  # for timezone info
+tzlocal==2.0          # for figuring out the local timezone; frozen to 2.0 because 3.0 conflicts the latest version of appscheduler (as of jan.2020)
diff --git a/requirements.txt b/requirements.txt
index be2ff6ee0..7fc75f5bf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,12 +1,2 @@
-click
-apscheduler
-flask>=0.9            # for monitoring the web-service
-jinja2==2.11.1		  # pinning this to avoid flask pulling in a later one which breaks python3.6
-sqlalchemy>=1.1.9     # for database support
-configparser          # for parsing the config-file
-psutil                # for logging extra CPU-info
-colorhash             # for hashing a string into a color
-numpy                 # for computing median and other stats
-pytz                  # for timezone info
-tzlocal==2.0          # for figuring out the local timezone; frozen to 2.0 because 3.0 conflicts the latest version of appscheduler (as of jan.2020)
+-r requirements-micro.txt
 scipy                 # for statistical analysis of latency measurements
diff --git a/setup.py b/setup.py
index f6bec7cd7..04186b6e8 100644
--- a/setup.py
+++ b/setup.py
@@ -1,10 +1,17 @@
 import json
 import os
+import sys
 
 import setuptools
 
 loc = os.path.dirname(os.path.abspath(__file__))
 
+micro = False
+if '--micro' in sys.argv:
+    micro = True
+    sys.argv.remove('--micro')
+    print('In micro mode')
+
 
 def get_description():
     with open(loc + '/docs/README.rst') as readme:
@@ -13,18 +20,40 @@ def get_description():
         return info + '\n\n' + changelog.read()
 
 
-with open(loc + '/requirements.txt') as f:
+with open(loc + '/requirements-micro.txt') as f:
     required = f.read().splitlines()
+if not micro:
+    with open(loc + '/requirements.txt') as f:
+        required.extend([req for req in f.read().splitlines() if req != '-r requirements-micro.txt'])
 
 with open('flask_monitoringdashboard/constants.json', 'r') as f:
     constants = json.load(f)
 
+if micro:
+    packages = setuptools.find_packages(include=[
+        'flask_monitoringdashboard',
+        'flask_monitoringdashboard.database',
+        'flask_monitoringdashboard.core',
+        'flask_monitoringdashboard.core.config',
+        'flask_monitoringdashboard.core.custom_graph',
+        'flask_monitoringdashboard.core.profiler',
+        'flask_monitoringdashboard.core.profiler.*',
+    ],
+        exclude=['flask_monitoringdashboard.controllers.*',
+                 'flask_monitoringdashboard.frontend.*',
+                 'flask_monitoringdashboard.views.*',
+                 'flask_monitoringdashboard.static.*',
+                 'tests', 'test.*']
+    )
+else:
+    packages = setuptools.find_packages()
+
 setuptools.setup(
-    name="Flask-MonitoringDashboard",
+    name="Flask-MonitoringDashboard" if not micro else "Flask-MonitoringDashboard-Micro",
     version=constants['version'],
     setup_requires=['setuptools_scm'],
-    packages=setuptools.find_packages(),
-    include_package_data=True,
+    packages=packages,
+    include_package_data=not micro,  # This is all the html files and things which are not needed in micro mode
     platforms='Any',
     zip_safe=False,
     test_suite='tests.get_test_suite',


Test patch:
diff --git a/tests/api/test_endpoint.py b/tests/api/test_endpoint.py
index e40127152..ceb963223 100644
--- a/tests/api/test_endpoint.py
+++ b/tests/api/test_endpoint.py
@@ -24,6 +24,7 @@ def test_overview(dashboard_user, request_1, request_2, endpoint, session):
 
     assert data['monitor'] == 3
     assert data['name'] == endpoint.name
+    assert data['blueprint'] == endpoint.name
 
 
 @pytest.mark.parametrize('request_1__group_by', ['42'])
diff --git a/tests/unit/core/test_blueprints.py b/tests/unit/core/test_blueprints.py
new file mode 100644
index 000000000..0f4de8410
--- /dev/null
+++ b/tests/unit/core/test_blueprints.py
@@ -0,0 +1,28 @@
+import pytest
+
+from flask_monitoringdashboard.core.blueprints import get_blueprint
+
+
+@pytest.mark.parametrize('name', ['Fiddler'])
+def test_get_blueprint(name):
+    actual = get_blueprint(name)
+    assert actual == 'Fiddler'
+
+
+@pytest.mark.parametrize('name', ['Anomander.Purake'])
+def test_get_blueprint_double_gives_first(name):
+    actual = get_blueprint(name)
+    assert actual == 'Anomander'
+
+
+@pytest.mark.parametrize('name', ['Karsa.Orlong.Toblakai'])
+def test_get_blueprint_triple_gives_first(name):
+    actual = get_blueprint(name)
+    assert actual == 'Karsa'
+
+
+@pytest.mark.usefixtures('request_context')
+@pytest.mark.parametrize('name', [''])
+def test_get_blueprint_blank_gives_blank(name):
+    actual = get_blueprint(name)
+    assert actual == ''