Repository: nautobot/nautobot-app-golden-config (language: python)

Issue:
Cannot Load diff2html or jquery need them to be in collectstatic
### Environment
* Python version:  3.6.8
* Nautobot version:  1.1.2
* nautobot-golden-config version:  0.9.0

When the web page loads it is producing errors when trying to fetch jquery.min.js, diff2html.min.css and diff2html.min.js since these are being pointed at on the Internet.   We run nautobot in an isolated environment so we have no access to the Internet, we would need these files accessible via static.  Also for plugins I am not sure if you added a project-static directory within the plugin would it get collected using ...   
`nautobot-server collectstatic`

### Steps to Reproduce
1.   Run in an isolated environment without internet access load the /plugins/golden-config/home/ page.
2.  In the inspect window under console you will see failed to load for those 3 files.

<!-- What did you expect to happen? -->
### Expected Behavior
Ability to pull these from the project-static .. static directory on the device running nautobot.


<!-- What happened instead? -->
### Observed Behavior
No functionality on the page for diff2html.

Update Dependencies, bump version to 0.9.10
Update Dependencies, bump version to 0.9.10
Configuration Compliance Export Gives Traceback
### Environment
* Python version:  3.6.13
* Nautobot version:  1.1.4
* nautobot-golden-config version:  0.9.9

If you go to the configuration compliance view plugins-->configuration compliance.  And click on the export button.  A traceback is raised.
### Steps to Reproduce
1. setup compliance and run it.
2. go to configuration compliance view
3. click export 

<!-- What did you expect to happen? -->
### Expected Behavior
Export of the results

<!-- What happened instead? -->
### Observed Behavior
Traceback.
```
<class 'django.core.exceptions.FieldError'>

Cannot resolve keyword 'feature' into field. Choices are: _custom_field_data, actual, compliance, compliance_int, created, destination_for_associations, device, device_id, extra, id, intended, last_updated, missing, ordered, rule, rule_id, source_for_associations, tagged_items, tags

Python version: 3.6.13
Nautobot version: 1.1.4
```


Discussion / hints:
Sorry, I missed this, will figure out a fix. 



Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f6fde648..02eb7604 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,27 @@
 # Changelog
 
+## v0.9.10 - 2021-11
+
+### Announcements
+
+- Nautobot Golden Config 0.9.X will officially not support versions after 1.2.X
+- Nautobot Golden Config 1.0.X will tentatively not support versions after 1.2.X
+- Nautobot Golden Config will maintain a `stable-<major>.<minor>` branch name
+- Nautobot Golden Config branching policy created
+
+### Added
+
+- #155 Contribution policy updated in Readme
+
+### Fixed
+
+- #129 Update filters, forms, add filters to api.
+- #148 move diff2html to be locally served
+- #154 Fix report bar chart overlap
+- #161 Fix configuration compliance export gives traceback
+- #164 Fixes the export functionality for configuration compliance list view.
+- #166 fix configuration and overview reporting csv exports
+
 ## v0.9.9 - 2021-10
 
 ### Fixed
diff --git a/README.md b/README.md
index 53e2768c..5f4f97aa 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,6 @@
 
 A plugin for [Nautobot](https://github.com/nautobot/nautobot) that intends to provide context around golden configuration.
 
-**This version is currently in Beta and will require a rebuild of the database for a 1.0 release.**
-
-
 # Introduction
 
 ## What is the Golden Configuration Plugin?
@@ -19,7 +16,7 @@ This plugin enable four (4) key use cases.
 1. **Configuration Backups** - Is a Nornir process to connect to devices, optionally parse out lines/secrets, backup the configuration, and save to a Git repository.
 2. **Intended Configuration** - Is a Nornir process to generate configuration based on a Git repo of Jinja files to combine with a GraphQL generated data and a Git repo to store the intended configuration.
 3. **Source of Truth Aggregation** - Is a GraphQL query per device that creates a data structure used in the generation of configuration.
-4. **Configuration Compliance** - Is a Nornir process to run comparison of the actual (via backups) and intended (via Jinja file creation) CLI configurations.
+4. **Configuration Compliance** - Is a process to run comparison of the actual (via backups) and intended (via Jinja file creation) CLI configurations upon saving the actual and intended configuration. This is started by either a Nornir process for cli-like configurations or calling the API for json-like configurations
 
 >Notice: The operator's of their own Nautobot instance are welcome to use any combination of these features. Though the appearance may seem like they are tightly 
 coupled, this isn't actually the case. For example, one can obtain backup configurations from their current RANCID/Oxidized process and simply provide a Git Repo
@@ -34,6 +31,7 @@ but not want to use other features, which is perfectly fine to do so.
 - [Navigating Intended](./docs/navigating-intended.md)
 - [Navigating SoTAgg](./docs/navigating-sot-agg.md)
 - [Navigating Compliance](./docs/navigating-compliance.md)
+- [Navigating JSON Compliance](./docs/navigating-compliance-json.md)
 - [FAQ](./docs/FAQ.md)
 
 ## Screenshots
@@ -65,6 +63,33 @@ The project is following Network to Code software development guidelines and are
 - Black, Pylint, Bandit, flake8, and pydocstyle for Python linting and formatting.
 - Django unit test to ensure the plugin is working properly.
 
+## Branching Policy
+
+The branching policy includes the following tenets:
+
+- The develop branch is the branch of the next major or minor version planned.
+- The `stable-<major>.<minor>` branch is the branch of the latest version within that major/minor version
+- PRs intended to add new features should be sourced from the develop branch
+- PRs intended to address bug fixes and security patches should be sourced from `stable-<major>.<minor>`
+
+Nautobot Golden Config will observe semantic versioning, as of 1.0. This may result in an quick turn around in minor versions to keep
+pace with an ever growing feature set.
+
+## Release Policy
+
+Nautobot Golden Config has currently no intended scheduled release schedule, and will release new feature in minor versions.
+
+## Deprecation Policy
+
+Support of upstream Nautobot will be announced 1 minor or major version ahead. Deprecation policy will be announced within the
+CHANGELOG.md file, and updated in the table below. There will be a `stable-<major>.<minor>` branch that will be minimally maintained.
+Any security enhancements or major bugs will be supported for a limited time. 
+
+| Golden Config Version | Nautobot First Support Version | Nautobot Last Support Version |
+| --------------------- | ------------------------------ | ----------------------------- |
+| 0.9.X                 | 1.0                            | 1.2 [Official]                |
+| 1.0.X                 | 1.2                            | 1.2 [Tentative]               |
+
 ## CLI Helper Commands
 
 The project features a CLI helper based on [invoke](http://www.pyinvoke.org/) to help setup the development environment. The commands are listed below in 3 categories:
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 1d3df7ed..df4ffbfa 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -43,13 +43,15 @@ _What are the supported platforms for Compliance jobs? How do I configure a devi
 The current supported platform and the associated *default* platform slug names are the following for:
 
 * arista_eos
+* bigip_f5
 * cisco_asa
 * cisco_ios
 * cisco_nxos
 * cisco_aireos
-* linux
 * bigip_f5
+* fortinet_fortios
 * juniper_junos
+* linux
 
 The expected "network_os" parameter must be as defined by netutils and golden config uses the platform slug to map from the device to the appropriate
 "network_os" that netutils expects. However, there an ability to map the actual platform slug for compliance and parsing tasks via the plugin settings in your
@@ -72,6 +74,7 @@ _What are the supported platforms for Backup and Intended Configuration jobs? Ho
 The current supported platform and the associated *default* platform slug names are the following for:
 
 * arista_eos
+* cisco_asa
 * cisco_ios
 * cisco_ios_xr
 * cisco_nxos
diff --git a/docs/installation.md b/docs/installation.md
index a5c355c9..422752a2 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -55,9 +55,9 @@ The plugin behavior can be controlled with the following list of settings.
 | enable_sotagg | True | True | A boolean to represent whether or not to provide a GraphQL query per device to allow the intended configuration to provide data variables to the plugin. |
 | platform_slug_map | {"cisco_wlc": "cisco_aireos"} | None | A dictionary in which the key is the platform slug and the value is what netutils uses in any "network_os" parameter. |
 | sot_agg_transposer | mypkg.transposer | - | A string representation of a function that can post-process the graphQL data. |
-| per_feature_bar_width | 0.15 | 0.15 | The width of the table bar within the overview report | 
-| per_feature_width | 13 | 13 | The width in inches that the overview table can be. | 
-| per_feature_height | 4 | 4 | The height in inches that the overview table can be. | 
+| per_feature_bar_width | 0.15 | 0.15 | The width of the table bar within the overview report |
+| per_feature_width | 13 | 13 | The width in inches that the overview table can be. |
+| per_feature_height | 4 | 4 | The height in inches that the overview table can be. |
 
 > Note: Over time the intention is to make the compliance report more dynamic, but for now allow users to configure the `per_*` configs in a way that fits best for them.
 
diff --git a/nautobot_golden_config/__init__.py b/nautobot_golden_config/__init__.py
index 820a8c3c..4df59cf7 100644
--- a/nautobot_golden_config/__init__.py
+++ b/nautobot_golden_config/__init__.py
@@ -1,6 +1,6 @@
 """Plugin declaration for nautobot_golden_config."""
 
-__version__ = "0.9.9"
+__version__ = "0.9.10"
 
 from nautobot.extras.plugins import PluginConfig
 
diff --git a/nautobot_golden_config/api/views.py b/nautobot_golden_config/api/views.py
index d9246fff..1da1d40f 100644
--- a/nautobot_golden_config/api/views.py
+++ b/nautobot_golden_config/api/views.py
@@ -10,6 +10,7 @@
 
 from nautobot_golden_config.api import serializers
 from nautobot_golden_config import models
+from nautobot_golden_config import filters
 from nautobot_golden_config.utilities.graphql import graph_ql_query
 
 
@@ -40,6 +41,7 @@ class ComplianceRuleViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many
 
     queryset = models.ComplianceRule.objects.all()
     serializer_class = serializers.ComplianceRuleSerializer
+    filterset_class = filters.ComplianceRuleFilterSet
 
 
 class ComplianceFeatureViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-ancestors
@@ -47,6 +49,7 @@ class ComplianceFeatureViewSet(CustomFieldModelViewSet):  # pylint:disable=too-m
 
     queryset = models.ComplianceFeature.objects.all()
     serializer_class = serializers.ComplianceFeatureSerializer
+    filterset_class = filters.ComplianceFeatureFilterSet
 
 
 class ConfigComplianceViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-ancestors
@@ -54,6 +57,7 @@ class ConfigComplianceViewSet(CustomFieldModelViewSet):  # pylint:disable=too-ma
 
     queryset = models.ConfigCompliance.objects.all()
     serializer_class = serializers.ConfigComplianceSerializer
+    filterset_class = filters.ConfigComplianceFilterSet
 
 
 class GoldenConfigViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-ancestors
@@ -61,6 +65,7 @@ class GoldenConfigViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-a
 
     queryset = models.GoldenConfig.objects.all()
     serializer_class = serializers.GoldenConfigSerializer
+    filterset_class = filters.GoldenConfigFilterSet
 
 
 class GoldenConfigSettingViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-ancestors
@@ -75,6 +80,7 @@ class ConfigRemoveViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-a
 
     queryset = models.ConfigRemove.objects.all()
     serializer_class = serializers.ConfigRemoveSerializer
+    filterset_class = filters.ConfigRemoveFilterSet
 
 
 class ConfigReplaceViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-ancestors
@@ -82,3 +88,4 @@ class ConfigReplaceViewSet(CustomFieldModelViewSet):  # pylint:disable=too-many-
 
     queryset = models.ConfigReplace.objects.all()
     serializer_class = serializers.ConfigReplaceSerializer
+    filterset_class = filters.ConfigReplaceFilterSet
diff --git a/nautobot_golden_config/filters.py b/nautobot_golden_config/filters.py
index b84f71e8..594a594d 100644
--- a/nautobot_golden_config/filters.py
+++ b/nautobot_golden_config/filters.py
@@ -1,105 +1,21 @@
-"""Filter for Device Configuration Backup."""
+"""Filters for UI and API Views."""
 
 import django_filters
 
 from django.db.models import Q
 
-from nautobot.dcim.models import Device, Platform, Region, Site, DeviceRole, DeviceType, Manufacturer, RackGroup, Rack
+from nautobot.dcim.models import Device, Platform, Region, Site, DeviceRole, DeviceType, Manufacturer, Rack, RackGroup
 from nautobot.extras.models import Status
-from nautobot.extras.filters import CreatedUpdatedFilterSet, StatusFilter, CustomFieldModelFilterSet
+from nautobot.extras.filters import StatusFilter, CustomFieldModelFilterSet
 from nautobot.tenancy.models import Tenant, TenantGroup
 from nautobot.utilities.filters import TreeNodeMultipleChoiceFilter
 
 from nautobot_golden_config import models
 
 
-class GoldenConfigFilterSet(CreatedUpdatedFilterSet):
-    """Filter capabilities for GoldenConfig instances."""
+class GenericPlatformFilterSet(CustomFieldModelFilterSet):
+    """Generic method to reuse common FilterSet."""
 
-    q = django_filters.CharFilter(
-        method="search",
-        label="Search",
-    )
-    tenant_group_id = TreeNodeMultipleChoiceFilter(
-        queryset=TenantGroup.objects.all(),
-        field_name="tenant__group",
-        lookup_expr="in",
-        label="Tenant Group (ID)",
-    )
-    tenant_group = TreeNodeMultipleChoiceFilter(
-        queryset=TenantGroup.objects.all(),
-        field_name="tenant__group",
-        to_field_name="slug",
-        lookup_expr="in",
-        label="Tenant Group (slug)",
-    )
-    tenant_id = django_filters.ModelMultipleChoiceFilter(
-        queryset=Tenant.objects.all(),
-        field_name="tenant_id",
-        label="Tenant (ID)",
-    )
-    tenant = django_filters.ModelMultipleChoiceFilter(
-        queryset=Tenant.objects.all(),
-        field_name="tenant__slug",
-        to_field_name="slug",
-        label="Tenant (slug)",
-    )
-    region_id = TreeNodeMultipleChoiceFilter(
-        queryset=Region.objects.all(),
-        field_name="site__region",
-        lookup_expr="in",
-        label="Region (ID)",
-    )
-    region = TreeNodeMultipleChoiceFilter(
-        queryset=Region.objects.all(),
-        field_name="site__region",
-        lookup_expr="in",
-        to_field_name="slug",
-        label="Region (slug)",
-    )
-    site_id = django_filters.ModelMultipleChoiceFilter(
-        queryset=Site.objects.all(),
-        label="Site (ID)",
-    )
-    site = django_filters.ModelMultipleChoiceFilter(
-        field_name="site__slug",
-        queryset=Site.objects.all(),
-        to_field_name="slug",
-        label="Site name (slug)",
-    )
-    rack_group_id = TreeNodeMultipleChoiceFilter(
-        queryset=RackGroup.objects.all(),
-        field_name="rack__group",
-        lookup_expr="in",
-        label="Rack group (ID)",
-    )
-    rack_id = django_filters.ModelMultipleChoiceFilter(
-        field_name="rack",
-        queryset=Rack.objects.all(),
-        label="Rack (ID)",
-    )
-    role_id = django_filters.ModelMultipleChoiceFilter(
-        field_name="device_role_id",
-        queryset=DeviceRole.objects.all(),
-        label="Role (ID)",
-    )
-    role = django_filters.ModelMultipleChoiceFilter(
-        field_name="device_role__slug",
-        queryset=DeviceRole.objects.all(),
-        to_field_name="slug",
-        label="Role (slug)",
-    )
-    manufacturer_id = django_filters.ModelMultipleChoiceFilter(
-        field_name="device_type__manufacturer",
-        queryset=Manufacturer.objects.all(),
-        label="Manufacturer (ID)",
-    )
-    manufacturer = django_filters.ModelMultipleChoiceFilter(
-        field_name="device_type__manufacturer__slug",
-        queryset=Manufacturer.objects.all(),
-        to_field_name="slug",
-        label="Manufacturer (slug)",
-    )
     platform_id = django_filters.ModelMultipleChoiceFilter(
         queryset=Platform.objects.all(),
         label="Platform (ID)",
@@ -110,67 +26,10 @@ class GoldenConfigFilterSet(CreatedUpdatedFilterSet):
         to_field_name="slug",
         label="Platform (slug)",
     )
-    device_status_id = StatusFilter(
-        field_name="status",
-        queryset=Status.objects.all(),
-        label="Device Status",
-    )
-    device_type_id = django_filters.ModelMultipleChoiceFilter(
-        field_name="device_type_id",
-        queryset=DeviceType.objects.all(),
-        label="Device type (ID)",
-    )
-    device_id = django_filters.ModelMultipleChoiceFilter(
-        field_name="device",
-        queryset=Device.objects.all(),
-        label="Device (ID)",
-    )
-    device = django_filters.ModelMultipleChoiceFilter(
-        field_name="name",
-        queryset=Device.objects.all(),
-        label="Device Name",
-    )
-
-    def search(self, queryset, name, value):  # pylint: disable=unused-argument,no-self-use
-        """Perform the filtered search."""
-        if not value.strip():
-            return queryset
-        # Chose only device, can be convinced more should be included
-        qs_filter = Q(name__icontains=value)
-        return queryset.filter(qs_filter)
 
-    class Meta:
-        """Meta class attributes for GoldenConfig."""
 
-        model = Device
-        distinct = True
-        fields = [
-            "q",
-            "tenant_group_id",
-            "tenant_group",
-            "tenant_id",
-            "tenant",
-            "region_id",
-            "region",
-            "site_id",
-            "site",
-            "rack_group_id",
-            "rack_id",
-            "role_id",
-            "role",
-            "manufacturer_id",
-            "manufacturer",
-            "platform_id",
-            "platform",
-            "device_status_id",
-            "device_type_id",
-            "device_id",
-            "device",
-        ]
-
-
-class ConfigComplianceFilterSet(CreatedUpdatedFilterSet):
-    """Filter capabilities for ConfigCompliance instances."""
+class GoldenConfigFilterSet(CustomFieldModelFilterSet):
+    """Filter capabilities for GoldenConfig instances."""
 
     q = django_filters.CharFilter(
         method="search",
@@ -214,6 +73,7 @@ class ConfigComplianceFilterSet(CreatedUpdatedFilterSet):
         label="Region (slug)",
     )
     site_id = django_filters.ModelMultipleChoiceFilter(
+        field_name="device__site",
         queryset=Site.objects.all(),
         label="Site (ID)",
     )
@@ -229,11 +89,23 @@ class ConfigComplianceFilterSet(CreatedUpdatedFilterSet):
         lookup_expr="in",
         label="Rack group (ID)",
     )
+    rack_group = django_filters.ModelMultipleChoiceFilter(
+        field_name="device__rack__group__slug",
+        queryset=RackGroup.objects.all(),
+        to_field_name="slug",
+        label="Rack group (slug)",
+    )
     rack_id = django_filters.ModelMultipleChoiceFilter(
         field_name="device__rack",
         queryset=Rack.objects.all(),
         label="Rack (ID)",
     )
+    rack = django_filters.ModelMultipleChoiceFilter(
+        field_name="device__rack__name",
+        queryset=Rack.objects.all(),
+        to_field_name="name",
+        label="Rack (name)",
+    )
     role_id = django_filters.ModelMultipleChoiceFilter(
         field_name="device__device_role_id",
         queryset=DeviceRole.objects.all(),
@@ -257,6 +129,7 @@ class ConfigComplianceFilterSet(CreatedUpdatedFilterSet):
         label="Manufacturer (slug)",
     )
     platform_id = django_filters.ModelMultipleChoiceFilter(
+        field_name="device__platform",
         queryset=Platform.objects.all(),
         label="Platform (ID)",
     )
@@ -267,6 +140,11 @@ class ConfigComplianceFilterSet(CreatedUpdatedFilterSet):
         label="Platform (slug)",
     )
     device_status_id = StatusFilter(
+        field_name="device__status_id",
+        queryset=Status.objects.all(),
+        label="Device Status",
+    )
+    device_status = StatusFilter(
         field_name="device__status",
         queryset=Status.objects.all(),
         label="Device Status",
@@ -276,13 +154,20 @@ class ConfigComplianceFilterSet(CreatedUpdatedFilterSet):
         queryset=DeviceType.objects.all(),
         label="Device type (ID)",
     )
+    device_type = django_filters.ModelMultipleChoiceFilter(
+        field_name="device__device_type__slug",
+        queryset=DeviceType.objects.all(),
+        to_field_name="slug",
+        label="DeviceType (slug)",
+    )
     device_id = django_filters.ModelMultipleChoiceFilter(
         queryset=Device.objects.all(),
-        label="Device Name",
+        label="Device ID",
     )
     device = django_filters.ModelMultipleChoiceFilter(
         field_name="device__name",
         queryset=Device.objects.all(),
+        to_field_name="name",
         label="Device Name",
     )
 
@@ -294,34 +179,22 @@ def search(self, queryset, name, value):  # pylint: disable=unused-argument,no-s
         qs_filter = Q(device__name__icontains=value)
         return queryset.filter(qs_filter)
 
+    class Meta:
+        """Meta class attributes for GoldenConfigFilter."""
+
+        model = models.GoldenConfig
+        distinct = True
+        fields = ["id"]
+
+
+class ConfigComplianceFilterSet(GoldenConfigFilterSet):
+    """Filter capabilities for ConfigCompliance instances."""
+
     class Meta:
         """Meta class attributes for ConfigComplianceFilter."""
 
         model = models.ConfigCompliance
-        distinct = True
-        fields = [
-            "q",
-            "tenant_group_id",
-            "tenant_group",
-            "tenant_id",
-            "tenant",
-            "region_id",
-            "region",
-            "site_id",
-            "site",
-            "rack_group_id",
-            "rack_id",
-            "role_id",
-            "role",
-            "manufacturer_id",
-            "manufacturer",
-            "platform_id",
-            "platform",
-            "device_status_id",
-            "device_type_id",
-            "device_id",
-            "device",
-        ]
+        fields = ["id"]
 
 
 class ComplianceFeatureFilterSet(CustomFieldModelFilterSet):
@@ -343,10 +216,10 @@ class Meta:
         """Boilerplate filter Meta data for compliance feature."""
 
         model = models.ComplianceFeature
-        fields = ["q", "name"]
+        fields = ["id", "name"]
 
 
-class ComplianceRuleFilterSet(CustomFieldModelFilterSet):
+class ComplianceRuleFilterSet(GenericPlatformFilterSet):
     """Inherits Base Class CustomFieldModelFilterSet."""
 
     q = django_filters.CharFilter(
@@ -365,24 +238,48 @@ class Meta:
         """Boilerplate filter Meta data for compliance rule."""
 
         model = models.ComplianceRule
-        fields = ["q", "platform", "feature"]
+        fields = ["feature", "id"]
 
 
-class ConfigRemoveFilterSet(CustomFieldModelFilterSet):
+class ConfigRemoveFilterSet(GenericPlatformFilterSet):
     """Inherits Base Class CustomFieldModelFilterSet."""
 
+    q = django_filters.CharFilter(
+        method="search",
+        label="Search",
+    )
+
+    def search(self, queryset, name, value):  # pylint: disable=unused-argument,no-self-use
+        """Perform the filtered search."""
+        if not value.strip():
+            return queryset
+        qs_filter = Q(name__icontains=value)
+        return queryset.filter(qs_filter)
+
     class Meta:
         """Boilerplate filter Meta data for Config Remove."""
 
         model = models.ConfigRemove
-        fields = ["platform", "name"]
+        fields = ["id", "name"]
 
 
-class ConfigReplaceFilterSet(CustomFieldModelFilterSet):
+class ConfigReplaceFilterSet(GenericPlatformFilterSet):
     """Inherits Base Class CustomFieldModelFilterSet."""
 
+    q = django_filters.CharFilter(
+        method="search",
+        label="Search",
+    )
+
+    def search(self, queryset, name, value):  # pylint: disable=unused-argument,no-self-use
+        """Perform the filtered search."""
+        if not value.strip():
+            return queryset
+        qs_filter = Q(name__icontains=value)
+        return queryset.filter(qs_filter)
+
     class Meta:
-        """Boilerplate filter Meta data for Config Remove."""
+        """Boilerplate filter Meta data for Config Replace."""
 
         model = models.ConfigReplace
-        fields = ["platform", "name"]
+        fields = ["id", "name"]
diff --git a/nautobot_golden_config/forms.py b/nautobot_golden_config/forms.py
index 58fa85e0..b9725291 100644
--- a/nautobot_golden_config/forms.py
+++ b/nautobot_golden_config/forms.py
@@ -10,15 +10,14 @@
 
 from nautobot_golden_config import models
 
+# ConfigCompliance
 
-class GoldenConfigFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm):
-    """Filter Form for GoldenConfig instances."""
-
-    model = Device
 
-    class Meta:
-        """Meta definitions of searchable fields."""
+class ConfigComplianceFilterForm(utilities_forms.BootstrapMixin, extras_forms.CustomFieldFilterForm):
+    """Filter Form for ConfigCompliance instances."""
 
+    model = models.ConfigCompliance
+    # Set field order to be explicit
     field_order = [
         "q",
         "tenant_group",
@@ -30,10 +29,11 @@ class Meta:
         "role",
         "manufacturer",
         "platform",
-        "device_status_id",
+        "device_status",
         "device_type_id",
         "device",
     ]
+
     q = forms.CharField(required=False, label="Search")
     tenant_group = utilities_forms.DynamicModelMultipleChoiceField(
         queryset=TenantGroup.objects.all(), to_field_name="slug", required=False, null_option="None"
@@ -77,6 +77,7 @@ class Meta:
         display_field="model",
         query_params={"manufacturer": "$manufacturer"},
     )
+
     platform = utilities_forms.DynamicModelMultipleChoiceField(
         queryset=Platform.objects.all(), to_field_name="slug", required=False, null_option="None"
     )
@@ -87,26 +88,17 @@ class Meta:
     def __init__(self, *args, **kwargs):
         """Required for status to work."""
         super().__init__(*args, **kwargs)
-        self.fields["device_status_id"] = utilities_forms.DynamicModelMultipleChoiceField(
+        self.fields["device_status"] = utilities_forms.DynamicModelMultipleChoiceField(
             required=False,
             queryset=Status.objects.all(),
             query_params={"content_types": Device._meta.label_lower},
             display_field="label",
             label="Device Status",
-            to_field_name="name",
+            to_field_name="slug",
         )
         self.order_fields(self.field_order)  # Reorder fields again
 
 
-# ConfigCompliance
-
-
-class ConfigComplianceFilterForm(GoldenConfigFilterForm):
-    """Filter Form for ConfigCompliance instances."""
-
-    model = models.ConfigCompliance
-
-
 # ComplianceRule
 
 
@@ -240,9 +232,12 @@ class ConfigRemoveFeatureFilterForm(utilities_forms.BootstrapMixin, extras_forms
     """Filter Form for Line Removal."""
 
     model = models.ConfigRemove
-
-    platform = utilities_forms.DynamicModelMultipleChoiceField(queryset=Platform.objects.all(), required=False)
-    name = utilities_forms.DynamicModelChoiceField(queryset=models.ConfigRemove.objects.all(), required=False)
+    platform = utilities_forms.DynamicModelMultipleChoiceField(
+        queryset=Platform.objects.all(), required=False, null_option="None"
+    )
+    name = utilities_forms.DynamicModelChoiceField(
+        queryset=models.ConfigRemove.objects.all(), to_field_name="name", required=False
+    )
 
 
 class ConfigRemoveBulkEditForm(
@@ -296,15 +291,19 @@ class ConfigReplaceFeatureFilterForm(utilities_forms.BootstrapMixin, extras_form
 
     model = models.ConfigReplace
 
-    platform = utilities_forms.DynamicModelMultipleChoiceField(queryset=Platform.objects.all(), required=False)
-    name = utilities_forms.DynamicModelChoiceField(queryset=models.ConfigReplace.objects.all(), required=False)
+    platform = utilities_forms.DynamicModelMultipleChoiceField(
+        queryset=Platform.objects.all(), to_field_name="slug", required=False, null_option="None"
+    )
+    name = utilities_forms.DynamicModelChoiceField(
+        queryset=models.ConfigReplace.objects.all(), to_field_name="name", required=False
+    )
 
 
 class ConfigReplaceCSVForm(extras_forms.CustomFieldModelCSVForm):
-    """CSV Form for ConfigRemove instances."""
+    """CSV Form for ConfigReplace instances."""
 
     class Meta:
-        """Boilerplate form Meta data for ConfigRemove."""
+        """Boilerplate form Meta data for ConfigReplace."""
 
         model = models.ConfigReplace
         fields = models.ConfigReplace.csv_headers
diff --git a/nautobot_golden_config/static/nautobot_golden_config/diff2html-3.4.13/diff2html.min.css b/nautobot_golden_config/static/nautobot_golden_config/diff2html-3.4.13/diff2html.min.css
new file mode 100644
index 00000000..efddec0d
--- /dev/null
+++ b/nautobot_golden_config/static/nautobot_golden_config/diff2html-3.4.13/diff2html.min.css
@@ -0,0 +1,1 @@
+.d2h-d-none{display:none}.d2h-wrapper{text-align:left}.d2h-file-header{background-color:#f7f7f7;border-bottom:1px solid #d8d8d8;font-family:Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;height:35px;padding:5px 10px}.d2h-file-header,.d2h-file-stats{display:-webkit-box;display:-ms-flexbox;display:flex}.d2h-file-stats{font-size:14px;margin-left:auto}.d2h-lines-added{border:1px solid #b4e2b4;border-radius:5px 0 0 5px;color:#399839;padding:2px;text-align:right;vertical-align:middle}.d2h-lines-deleted{border:1px solid #e9aeae;border-radius:0 5px 5px 0;color:#c33;margin-left:1px;padding:2px;text-align:left;vertical-align:middle}.d2h-file-name-wrapper{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;font-size:15px;width:100%}.d2h-file-name{overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-file-collapse{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid #ddd;border-radius:3px;cursor:pointer;display:none;font-size:12px;justify-content:flex-end;padding:4px 8px}.d2h-file-collapse.d2h-selected{background-color:#c8e1ff}.d2h-file-collapse-input{margin:0 4px 0 0}.d2h-diff-table{border-collapse:collapse;font-family:Menlo,Consolas,monospace;font-size:13px;width:100%}.d2h-files-diff{width:100%}.d2h-file-diff{overflow-y:hidden}.d2h-file-side-diff{display:inline-block;margin-bottom:-8px;margin-right:-4px;overflow-x:scroll;overflow-y:hidden;width:50%}.d2h-code-line{padding:0 8em}.d2h-code-line,.d2h-code-side-line{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;width:100%}.d2h-code-side-line{padding:0 4.5em}.d2h-code-line-ctn{word-wrap:normal;background:none;display:inline-block;padding:0;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;vertical-align:middle;white-space:pre;width:100%}.d2h-code-line del,.d2h-code-side-line del{background-color:#ffb6ba}.d2h-code-line del,.d2h-code-line ins,.d2h-code-side-line del,.d2h-code-side-line ins{border-radius:.2em;display:inline-block;margin-top:-1px;text-decoration:none;vertical-align:middle}.d2h-code-line ins,.d2h-code-side-line ins{background-color:#97f295;text-align:left}.d2h-code-line-prefix{word-wrap:normal;background:none;display:inline;padding:0;white-space:pre}.line-num1{float:left}.line-num1,.line-num2{-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;padding:0 .5em;text-overflow:ellipsis;width:3.5em}.line-num2{float:right}.d2h-code-linenumber{background-color:#fff;border:solid #eee;border-width:0 1px;-webkit-box-sizing:border-box;box-sizing:border-box;color:rgba(0,0,0,.3);cursor:pointer;display:inline-block;position:absolute;text-align:right;width:7.5em}.d2h-code-linenumber:after{content:"\200b"}.d2h-code-side-linenumber{background-color:#fff;border:solid #eee;border-width:0 1px;-webkit-box-sizing:border-box;box-sizing:border-box;color:rgba(0,0,0,.3);cursor:pointer;display:inline-block;overflow:hidden;padding:0 .5em;position:absolute;text-align:right;text-overflow:ellipsis;width:4em}.d2h-code-side-linenumber:after{content:"\200b"}.d2h-code-side-emptyplaceholder,.d2h-emptyplaceholder{background-color:#f1f1f1;border-color:#e1e1e1}.d2h-code-line-prefix,.d2h-code-linenumber,.d2h-code-side-linenumber,.d2h-emptyplaceholder{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.d2h-code-linenumber,.d2h-code-side-linenumber{direction:rtl}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;border-color:#d5e4f2;color:rgba(0,0,0,.3)}.d2h-file-diff .d2h-del.d2h-change{background-color:#fdf2d0}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-list-wrapper{margin-bottom:10px}.d2h-file-list-wrapper a{color:#3572b0;text-decoration:none}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{text-align:left}.d2h-file-list-title{font-weight:700}.d2h-file-list-line{display:-webkit-box;display:-ms-flexbox;display:flex;text-align:left}.d2h-file-list{display:block;list-style:none;margin:0;padding:0}.d2h-file-list>li{border-bottom:1px solid #ddd;margin:0;padding:5px 10px}.d2h-file-list>li:last-child{border-bottom:none}.d2h-file-switch{cursor:pointer;display:none;font-size:10px}.d2h-icon{fill:currentColor;margin-right:10px;vertical-align:middle}.d2h-deleted{color:#c33}.d2h-added{color:#399839}.d2h-changed{color:#d0b44c}.d2h-moved{color:#3572b0}.d2h-tag{background-color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;font-size:10px;margin-left:5px;padding:0 2px}.d2h-deleted-tag{border:1px solid #c33}.d2h-added-tag{border:1px solid #399839}.d2h-changed-tag{border:1px solid #d0b44c}.d2h-moved-tag{border:1px solid #3572b0}
\ No newline at end of file
diff --git a/nautobot_golden_config/static/nautobot_golden_config/diff2html-3.4.13/diff2html.min.js b/nautobot_golden_config/static/nautobot_golden_config/diff2html-3.4.13/diff2html.min.js
new file mode 100644
index 00000000..2cbafda5
--- /dev/null
+++ b/nautobot_golden_config/static/nautobot_golden_config/diff2html-3.4.13/diff2html.min.js
@@ -0,0 +1,1 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Diff2Html",[],t):"object"==typeof exports?exports.Diff2Html=t():e.Diff2Html=t()}(this,(function(){return e={696:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.convertChangesToDMP=function(e){for(var t,n,i=[],r=0;r<e.length;r++)n=(t=e[r]).added?1:t.removed?-1:0,i.push([n,t.value]);return i}},826:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.convertChangesToXML=function(e){for(var t=[],n=0;n<e.length;n++){var i=e[n];i.added?t.push("<ins>"):i.removed&&t.push("<del>"),t.push(i.value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")),i.added?t.push("</ins>"):i.removed&&t.push("</del>")}return t.join("")}},976:(e,t,n)=>{"use strict";var i;Object.defineProperty(t,"__esModule",{value:!0}),t.diffArrays=function(e,t,n){return r.diff(e,t,n)},t.arrayDiff=void 0;var r=new(((i=n(913))&&i.__esModule?i:{default:i}).default);t.arrayDiff=r,r.tokenize=function(e){return e.slice()},r.join=r.removeEmpty=function(e){return e}},913:(e,t)=>{"use strict";function n(){}function i(e,t,n,i,r){for(var a=0,o=t.length,s=0,l=0;a<o;a++){var f=t[a];if(f.removed){if(f.value=e.join(i.slice(l,l+f.count)),l+=f.count,a&&t[a-1].added){var u=t[a-1];t[a-1]=t[a],t[a]=u}}else{if(!f.added&&r){var d=n.slice(s,s+f.count);d=d.map((function(e,t){var n=i[l+t];return n.length>e.length?n:e})),f.value=e.join(d)}else f.value=e.join(n.slice(s,s+f.count));s+=f.count,f.added||(l+=f.count)}}var c=t[o-1];return o>1&&"string"==typeof c.value&&(c.added||c.removed)&&e.equals("",c.value)&&(t[o-2].value+=c.value,t.pop()),t}function r(e){return{newPos:e.newPos,components:e.components.slice(0)}}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n,n.prototype={diff:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=n.callback;"function"==typeof n&&(a=n,n={}),this.options=n;var o=this;function s(e){return a?(setTimeout((function(){a(void 0,e)}),0),!0):e}e=this.castInput(e),t=this.castInput(t),e=this.removeEmpty(this.tokenize(e));var l=(t=this.removeEmpty(this.tokenize(t))).length,f=e.length,u=1,d=l+f,c=[{newPos:-1,components:[]}],h=this.extractCommon(c[0],t,e,0);if(c[0].newPos+1>=l&&h+1>=f)return s([{value:this.join(t),count:t.length}]);function p(){for(var n=-1*u;n<=u;n+=2){var a=void 0,d=c[n-1],h=c[n+1],p=(h?h.newPos:0)-n;d&&(c[n-1]=void 0);var b=d&&d.newPos+1<l,g=h&&0<=p&&p<f;if(b||g){if(!b||g&&d.newPos<h.newPos?(a=r(h),o.pushComponent(a.components,void 0,!0)):((a=d).newPos++,o.pushComponent(a.components,!0,void 0)),p=o.extractCommon(a,t,e,n),a.newPos+1>=l&&p+1>=f)return s(i(o,a.components,t,e,o.useLongestToken));c[n]=a}else c[n]=void 0}u++}if(a)!function e(){setTimeout((function(){if(u>d)return a();p()||e()}),0)}();else for(;u<=d;){var b=p();if(b)return b}},pushComponent:function(e,t,n){var i=e[e.length-1];i&&i.added===t&&i.removed===n?e[e.length-1]={count:i.count+1,added:t,removed:n}:e.push({count:1,added:t,removed:n})},extractCommon:function(e,t,n,i){for(var r=t.length,a=n.length,o=e.newPos,s=o-i,l=0;o+1<r&&s+1<a&&this.equals(t[o+1],n[s+1]);)o++,s++,l++;return l&&e.components.push({count:l}),e.newPos=o,s},equals:function(e,t){return this.options.comparator?this.options.comparator(e,t):e===t||this.options.ignoreCase&&e.toLowerCase()===t.toLowerCase()},removeEmpty:function(e){for(var t=[],n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t},castInput:function(e){return e},tokenize:function(e){return e.split("")},join:function(e){return e.join("")}}},630:(e,t,n)=>{"use strict";var i;Object.defineProperty(t,"__esModule",{value:!0}),t.diffChars=function(e,t,n){return r.diff(e,t,n)},t.characterDiff=void 0;var r=new(((i=n(913))&&i.__esModule?i:{default:i}).default);t.characterDiff=r},852:(e,t,n)=>{"use strict";var i;Object.defineProperty(t,"__esModule",{value:!0}),t.diffCss=function(e,t,n){return r.diff(e,t,n)},t.cssDiff=void 0;var r=new(((i=n(913))&&i.__esModule?i:{default:i}).default);t.cssDiff=r,r.tokenize=function(e){return e.split(/([{}:;,]|\s+)/)}},276:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.diffJson=function(e,t,n){return l.diff(e,t,n)},t.canonicalize=f,t.jsonDiff=void 0;var i,r=(i=n(913))&&i.__esModule?i:{default:i},a=n(187);function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var s=Object.prototype.toString,l=new r.default;function f(e,t,n,i,r){var a,l;for(t=t||[],n=n||[],i&&(e=i(r,e)),a=0;a<t.length;a+=1)if(t[a]===e)return n[a];if("[object Array]"===s.call(e)){for(t.push(e),l=new Array(e.length),n.push(l),a=0;a<e.length;a+=1)l[a]=f(e[a],t,n,i,r);return t.pop(),n.pop(),l}if(e&&e.toJSON&&(e=e.toJSON()),"object"===o(e)&&null!==e){t.push(e),l={},n.push(l);var u,d=[];for(u in e)e.hasOwnProperty(u)&&d.push(u);for(d.sort(),a=0;a<d.length;a+=1)l[u=d[a]]=f(e[u],t,n,i,u);t.pop(),n.pop()}else l=e;return l}t.jsonDiff=l,l.useLongestToken=!0,l.tokenize=a.lineDiff.tokenize,l.castInput=function(e){var t=this.options,n=t.undefinedReplacement,i=t.stringifyReplacer,r=void 0===i?function(e,t){return void 0===t?n:t}:i;return"string"==typeof e?e:JSON.stringify(f(e,null,null,r),r,"  ")},l.equals=function(e,t){return r.default.prototype.equals.call(l,e.replace(/,([\r\n])/g,"$1"),t.replace(/,([\r\n])/g,"$1"))}},187:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.diffLines=function(e,t,n){return o.diff(e,t,n)},t.diffTrimmedLines=function(e,t,n){var i=(0,a.generateOptions)(n,{ignoreWhitespace:!0});return o.diff(e,t,i)},t.lineDiff=void 0;var i,r=(i=n(913))&&i.__esModule?i:{default:i},a=n(9),o=new r.default;t.lineDiff=o,o.tokenize=function(e){var t=[],n=e.split(/(\n|\r\n)/);n[n.length-1]||n.pop();for(var i=0;i<n.length;i++){var r=n[i];i%2&&!this.options.newlineIsToken?t[t.length-1]+=r:(this.options.ignoreWhitespace&&(r=r.trim()),t.push(r))}return t}},146:(e,t,n)=>{"use strict";var i;Object.defineProperty(t,"__esModule",{value:!0}),t.diffSentences=function(e,t,n){return r.diff(e,t,n)},t.sentenceDiff=void 0;var r=new(((i=n(913))&&i.__esModule?i:{default:i}).default);t.sentenceDiff=r,r.tokenize=function(e){return e.split(/(\S.+?[.!?])(?=\s+|$)/)}},303:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.diffWords=function(e,t,n){return n=(0,a.generateOptions)(n,{ignoreWhitespace:!0}),l.diff(e,t,n)},t.diffWordsWithSpace=function(e,t,n){return l.diff(e,t,n)},t.wordDiff=void 0;var i,r=(i=n(913))&&i.__esModule?i:{default:i},a=n(9),o=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,s=/\S/,l=new r.default;t.wordDiff=l,l.equals=function(e,t){return this.options.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e===t||this.options.ignoreWhitespace&&!s.test(e)&&!s.test(t)},l.tokenize=function(e){for(var t=e.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),n=0;n<t.length-1;n++)!t[n+1]&&t[n+2]&&o.test(t[n])&&o.test(t[n+2])&&(t[n]+=t[n+2],t.splice(n+1,2),n--);return t}},785:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"Diff",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(t,"diffChars",{enumerable:!0,get:function(){return a.diffChars}}),Object.defineProperty(t,"diffWords",{enumerable:!0,get:function(){return o.diffWords}}),Object.defineProperty(t,"diffWordsWithSpace",{enumerable:!0,get:function(){return o.diffWordsWithSpace}}),Object.defineProperty(t,"diffLines",{enumerable:!0,get:function(){return s.diffLines}}),Object.defineProperty(t,"diffTrimmedLines",{enumerable:!0,get:function(){return s.diffTrimmedLines}}),Object.defineProperty(t,"diffSentences",{enumerable:!0,get:function(){return l.diffSentences}}),Object.defineProperty(t,"diffCss",{enumerable:!0,get:function(){return f.diffCss}}),Object.defineProperty(t,"diffJson",{enumerable:!0,get:function(){return u.diffJson}}),Object.defineProperty(t,"canonicalize",{enumerable:!0,get:function(){return u.canonicalize}}),Object.defineProperty(t,"diffArrays",{enumerable:!0,get:function(){return d.diffArrays}}),Object.defineProperty(t,"applyPatch",{enumerable:!0,get:function(){return c.applyPatch}}),Object.defineProperty(t,"applyPatches",{enumerable:!0,get:function(){return c.applyPatches}}),Object.defineProperty(t,"parsePatch",{enumerable:!0,get:function(){return h.parsePatch}}),Object.defineProperty(t,"merge",{enumerable:!0,get:function(){return p.merge}}),Object.defineProperty(t,"structuredPatch",{enumerable:!0,get:function(){return b.structuredPatch}}),Object.defineProperty(t,"createTwoFilesPatch",{enumerable:!0,get:function(){return b.createTwoFilesPatch}}),Object.defineProperty(t,"createPatch",{enumerable:!0,get:function(){return b.createPatch}}),Object.defineProperty(t,"convertChangesToDMP",{enumerable:!0,get:function(){return g.convertChangesToDMP}}),Object.defineProperty(t,"convertChangesToXML",{enumerable:!0,get:function(){return v.convertChangesToXML}});var i,r=(i=n(913))&&i.__esModule?i:{default:i},a=n(630),o=n(303),s=n(187),l=n(146),f=n(852),u=n(276),d=n(976),c=n(690),h=n(719),p=n(51),b=n(286),g=n(696),v=n(826)},690:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.applyPatch=o,t.applyPatches=function(e,t){"string"==typeof e&&(e=(0,r.parsePatch)(e));var n=0;!function i(){var r=e[n++];if(!r)return t.complete();t.loadFile(r,(function(e,n){if(e)return t.complete(e);var a=o(n,r,t);t.patched(r,a,(function(e){if(e)return t.complete(e);i()}))}))}()};var i,r=n(719),a=(i=n(169))&&i.__esModule?i:{default:i};function o(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"==typeof t&&(t=(0,r.parsePatch)(t)),Array.isArray(t)){if(t.length>1)throw new Error("applyPatch only works with a single input.");t=t[0]}var i,o,s=e.split(/\r\n|[\n\v\f\r\x85]/),l=e.match(/\r\n|[\n\v\f\r\x85]/g)||[],f=t.hunks,u=n.compareLine||function(e,t,n,i){return t===i},d=0,c=n.fuzzFactor||0,h=0,p=0;function b(e,t){for(var n=0;n<e.lines.length;n++){var i=e.lines[n],r=i.length>0?i[0]:" ",a=i.length>0?i.substr(1):i;if(" "===r||"-"===r){if(!u(t+1,s[t],r,a)&&++d>c)return!1;t++}}return!0}for(var g=0;g<f.length;g++){for(var v=f[g],m=s.length-v.oldLines,y=0,w=p+v.oldStart-1,L=(0,a.default)(w,h,m);void 0!==y;y=L())if(b(v,w+y)){v.offset=p+=y;break}if(void 0===y)return!1;h=v.offset+v.oldStart+v.oldLines}for(var S=0,x=0;x<f.length;x++){var C=f[x],T=C.oldStart+C.offset+S-1;S+=C.newLines-C.oldLines;for(var _=0;_<C.lines.length;_++){var N=C.lines[_],O=N.length>0?N[0]:" ",P=N.length>0?N.substr(1):N,j=C.linedelimiters[_];if(" "===O)T++;else if("-"===O)s.splice(T,1),l.splice(T,1);else if("+"===O)s.splice(T,0,P),l.splice(T,0,j),T++;else if("\\"===O){var E=C.lines[_-1]?C.lines[_-1][0]:null;"+"===E?i=!0:"-"===E&&(o=!0)}}}if(i)for(;!s[s.length-1];)s.pop(),l.pop();else o&&(s.push(""),l.push("\n"));for(var M=0;M<s.length-1;M++)s[M]=s[M]+l[M];return s.join("")}},286:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.structuredPatch=o,t.formatPatch=s,t.createTwoFilesPatch=l,t.createPatch=function(e,t,n,i,r,a){return l(e,e,t,n,i,r,a)};var i=n(187);function r(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?a(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function o(e,t,n,a,o,s,l){l||(l={}),void 0===l.context&&(l.context=4);var f=(0,i.diffLines)(n,a,l);function u(e){return e.map((function(e){return" "+e}))}f.push({value:"",lines:[]});for(var d=[],c=0,h=0,p=[],b=1,g=1,v=function(e){var t=f[e],i=t.lines||t.value.replace(/\n$/,"").split("\n");if(t.lines=i,t.added||t.removed){var o;if(!c){var s=f[e-1];c=b,h=g,s&&(p=l.context>0?u(s.lines.slice(-l.context)):[],c-=p.length,h-=p.length)}(o=p).push.apply(o,r(i.map((function(e){return(t.added?"+":"-")+e})))),t.added?g+=i.length:b+=i.length}else{if(c)if(i.length<=2*l.context&&e<f.length-2){var v;(v=p).push.apply(v,r(u(i)))}else{var m,y=Math.min(i.length,l.context);(m=p).push.apply(m,r(u(i.slice(0,y))));var w={oldStart:c,oldLines:b-c+y,newStart:h,newLines:g-h+y,lines:p};if(e>=f.length-2&&i.length<=l.context){var L=/\n$/.test(n),S=/\n$/.test(a),x=0==i.length&&p.length>w.oldLines;!L&&x&&n.length>0&&p.splice(w.oldLines,0,"\\ No newline at end of file"),(L||x)&&S||p.push("\\ No newline at end of file")}d.push(w),c=0,h=0,p=[]}b+=i.length,g+=i.length}},m=0;m<f.length;m++)v(m);return{oldFileName:e,newFileName:t,oldHeader:o,newHeader:s,hunks:d}}function s(e){var t=[];e.oldFileName==e.newFileName&&t.push("Index: "+e.oldFileName),t.push("==================================================================="),t.push("--- "+e.oldFileName+(void 0===e.oldHeader?"":"\t"+e.oldHeader)),t.push("+++ "+e.newFileName+(void 0===e.newHeader?"":"\t"+e.newHeader));for(var n=0;n<e.hunks.length;n++){var i=e.hunks[n];0===i.oldLines&&(i.oldStart-=1),0===i.newLines&&(i.newStart-=1),t.push("@@ -"+i.oldStart+","+i.oldLines+" +"+i.newStart+","+i.newLines+" @@"),t.push.apply(t,i.lines)}return t.join("\n")+"\n"}function l(e,t,n,i,r,a,l){return s(o(e,t,n,i,r,a,l))}},51:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.calcLineCount=l,t.merge=function(e,t,n){e=f(e,n),t=f(t,n);var i={};(e.index||t.index)&&(i.index=e.index||t.index),(e.newFileName||t.newFileName)&&(u(e)?u(t)?(i.oldFileName=d(i,e.oldFileName,t.oldFileName),i.newFileName=d(i,e.newFileName,t.newFileName),i.oldHeader=d(i,e.oldHeader,t.oldHeader),i.newHeader=d(i,e.newHeader,t.newHeader)):(i.oldFileName=e.oldFileName,i.newFileName=e.newFileName,i.oldHeader=e.oldHeader,i.newHeader=e.newHeader):(i.oldFileName=t.oldFileName||e.oldFileName,i.newFileName=t.newFileName||e.newFileName,i.oldHeader=t.oldHeader||e.oldHeader,i.newHeader=t.newHeader||e.newHeader)),i.hunks=[];for(var r=0,a=0,o=0,s=0;r<e.hunks.length||a<t.hunks.length;){var l=e.hunks[r]||{oldStart:1/0},b=t.hunks[a]||{oldStart:1/0};if(c(l,b))i.hunks.push(h(l,o)),r++,s+=l.newLines-l.oldLines;else if(c(b,l))i.hunks.push(h(b,s)),a++,o+=b.newLines-b.oldLines;else{var g={oldStart:Math.min(l.oldStart,b.oldStart),oldLines:0,newStart:Math.min(l.newStart+o,b.oldStart+s),newLines:0,lines:[]};p(g,l.oldStart,l.lines,b.oldStart,b.lines),a++,r++,i.hunks.push(g)}}return i};var i=n(286),r=n(719),a=n(780);function o(e){return function(e){if(Array.isArray(e))return s(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function l(e){var t=x(e.lines),n=t.oldLines,i=t.newLines;void 0!==n?e.oldLines=n:delete e.oldLines,void 0!==i?e.newLines=i:delete e.newLines}function f(e,t){if("string"==typeof e){if(/^@@/m.test(e)||/^Index:/m.test(e))return(0,r.parsePatch)(e)[0];if(!t)throw new Error("Must provide a base reference or pass in a patch");return(0,i.structuredPatch)(void 0,void 0,t,e)}return e}function u(e){return e.newFileName&&e.newFileName!==e.oldFileName}function d(e,t,n){return t===n?t:(e.conflict=!0,{mine:t,theirs:n})}function c(e,t){return e.oldStart<t.oldStart&&e.oldStart+e.oldLines<t.oldStart}function h(e,t){return{oldStart:e.oldStart,oldLines:e.oldLines,newStart:e.newStart+t,newLines:e.newLines,lines:e.lines}}function p(e,t,n,i,r){var a={offset:t,lines:n,index:0},s={offset:i,lines:r,index:0};for(m(e,a,s),m(e,s,a);a.index<a.lines.length&&s.index<s.lines.length;){var f=a.lines[a.index],u=s.lines[s.index];if("-"!==f[0]&&"+"!==f[0]||"-"!==u[0]&&"+"!==u[0])if("+"===f[0]&&" "===u[0]){var d;(d=e.lines).push.apply(d,o(w(a)))}else if("+"===u[0]&&" "===f[0]){var c;(c=e.lines).push.apply(c,o(w(s)))}else"-"===f[0]&&" "===u[0]?g(e,a,s):"-"===u[0]&&" "===f[0]?g(e,s,a,!0):f===u?(e.lines.push(f),a.index++,s.index++):v(e,w(a),w(s));else b(e,a,s)}y(e,a),y(e,s),l(e)}function b(e,t,n){var i=w(t),r=w(n);if(L(i)&&L(r)){var s,l;if((0,a.arrayStartsWith)(i,r)&&S(n,i,i.length-r.length))return void(s=e.lines).push.apply(s,o(i));if((0,a.arrayStartsWith)(r,i)&&S(t,r,r.length-i.length))return void(l=e.lines).push.apply(l,o(r))}else if((0,a.arrayEqual)(i,r)){var f;return void(f=e.lines).push.apply(f,o(i))}v(e,i,r)}function g(e,t,n,i){var r,a=w(t),s=function(e,t){for(var n=[],i=[],r=0,a=!1,o=!1;r<t.length&&e.index<e.lines.length;){var s=e.lines[e.index],l=t[r];if("+"===l[0])break;if(a=a||" "!==s[0],i.push(l),r++,"+"===s[0])for(o=!0;"+"===s[0];)n.push(s),s=e.lines[++e.index];l.substr(1)===s.substr(1)?(n.push(s),e.index++):o=!0}if("+"===(t[r]||"")[0]&&a&&(o=!0),o)return n;for(;r<t.length;)i.push(t[r++]);return{merged:i,changes:n}}(n,a);s.merged?(r=e.lines).push.apply(r,o(s.merged)):v(e,i?s:a,i?a:s)}function v(e,t,n){e.conflict=!0,e.lines.push({conflict:!0,mine:t,theirs:n})}function m(e,t,n){for(;t.offset<n.offset&&t.index<t.lines.length;){var i=t.lines[t.index++];e.lines.push(i),t.offset++}}function y(e,t){for(;t.index<t.lines.length;){var n=t.lines[t.index++];e.lines.push(n)}}function w(e){for(var t=[],n=e.lines[e.index][0];e.index<e.lines.length;){var i=e.lines[e.index];if("-"===n&&"+"===i[0]&&(n="+"),n!==i[0])break;t.push(i),e.index++}return t}function L(e){return e.reduce((function(e,t){return e&&"-"===t[0]}),!0)}function S(e,t,n){for(var i=0;i<n;i++){var r=t[t.length-n+i].substr(1);if(e.lines[e.index+i]!==" "+r)return!1}return e.index+=n,!0}function x(e){var t=0,n=0;return e.forEach((function(e){if("string"!=typeof e){var i=x(e.mine),r=x(e.theirs);void 0!==t&&(i.oldLines===r.oldLines?t+=i.oldLines:t=void 0),void 0!==n&&(i.newLines===r.newLines?n+=i.newLines:n=void 0)}else void 0===n||"+"!==e[0]&&" "!==e[0]||n++,void 0===t||"-"!==e[0]&&" "!==e[0]||t++})),{oldLines:t,newLines:n}}},719:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.parsePatch=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.split(/\r\n|[\n\v\f\r\x85]/),i=e.match(/\r\n|[\n\v\f\r\x85]/g)||[],r=[],a=0;function o(){var e={};for(r.push(e);a<n.length;){var i=n[a];if(/^(\-\-\-|\+\+\+|@@)\s/.test(i))break;var o=/^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(i);o&&(e.index=o[1]),a++}for(s(e),s(e),e.hunks=[];a<n.length;){var f=n[a];if(/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(f))break;if(/^@@/.test(f))e.hunks.push(l());else{if(f&&t.strict)throw new Error("Unknown line "+(a+1)+" "+JSON.stringify(f));a++}}}function s(e){var t=/^(---|\+\+\+)\s+(.*)$/.exec(n[a]);if(t){var i="---"===t[1]?"old":"new",r=t[2].split("\t",2),o=r[0].replace(/\\\\/g,"\\");/^".*"$/.test(o)&&(o=o.substr(1,o.length-2)),e[i+"FileName"]=o,e[i+"Header"]=(r[1]||"").trim(),a++}}function l(){var e=a,r=n[a++].split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/),o={oldStart:+r[1],oldLines:void 0===r[2]?1:+r[2],newStart:+r[3],newLines:void 0===r[4]?1:+r[4],lines:[],linedelimiters:[]};0===o.oldLines&&(o.oldStart+=1),0===o.newLines&&(o.newStart+=1);for(var s=0,l=0;a<n.length&&!(0===n[a].indexOf("--- ")&&a+2<n.length&&0===n[a+1].indexOf("+++ ")&&0===n[a+2].indexOf("@@"));a++){var f=0==n[a].length&&a!=n.length-1?" ":n[a][0];if("+"!==f&&"-"!==f&&" "!==f&&"\\"!==f)break;o.lines.push(n[a]),o.linedelimiters.push(i[a]||"\n"),"+"===f?s++:"-"===f?l++:" "===f&&(s++,l++)}if(s||1!==o.newLines||(o.newLines=0),l||1!==o.oldLines||(o.oldLines=0),t.strict){if(s!==o.newLines)throw new Error("Added line count did not match for hunk at line "+(e+1));if(l!==o.oldLines)throw new Error("Removed line count did not match for hunk at line "+(e+1))}return o}for(;a<n.length;)o();return r}},780:(e,t)=>{"use strict";function n(e,t){if(t.length>e.length)return!1;for(var n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}Object.defineProperty(t,"__esModule",{value:!0}),t.arrayEqual=function(e,t){return e.length===t.length&&n(e,t)},t.arrayStartsWith=n},169:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n){var i=!0,r=!1,a=!1,o=1;return function s(){if(i&&!a){if(r?o++:i=!1,e+o<=n)return o;a=!0}if(!r)return a||(i=!0),t<=e-o?-o++:(r=!0,s())}}},9:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.generateOptions=function(e,t){if("function"==typeof e)t.callback=e;else if(e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}},397:(e,t)=>{!function(e){var t=/\S/,n=/\"/g,i=/\n/g,r=/\r/g,a=/\\/g,o=/\u2028/,s=/\u2029/;function l(e){return e.trim?e.trim():e.replace(/^\s*|\s*$/g,"")}function f(e,t,n){if(t.charAt(n)!=e.charAt(0))return!1;for(var i=1,r=e.length;i<r;i++)if(t.charAt(n+i)!=e.charAt(i))return!1;return!0}e.tags={"#":1,"^":2,"<":3,$:4,"/":5,"!":6,">":7,"=":8,_v:9,"{":10,"&":11,_t:12},e.scan=function(n,i){var r,a=n.length,o=0,s=null,u=null,d="",c=[],h=!1,p=0,b=0,g="{{",v="}}";function m(){d.length>0&&(c.push({tag:"_t",text:new String(d)}),d="")}function y(n,i){if(m(),n&&function(){for(var n=!0,i=b;i<c.length;i++)if(!(n=e.tags[c[i].tag]<e.tags._v||"_t"==c[i].tag&&null===c[i].text.match(t)))return!1;return n}())for(var r,a=b;a<c.length;a++)c[a].text&&((r=c[a+1])&&">"==r.tag&&(r.indent=c[a].text.toString()),c.splice(a,1));else i||c.push({tag:"\n"});h=!1,b=c.length}function w(e,t){var n="="+v,i=e.indexOf(n,t),r=l(e.substring(e.indexOf("=",t)+1,i)).split(" ");return g=r[0],v=r[r.length-1],i+n.length-1}for(i&&(i=i.split(" "),g=i[0],v=i[1]),p=0;p<a;p++)0==o?f(g,n,p)?(--p,m(),o=1):"\n"==n.charAt(p)?y(h):d+=n.charAt(p):1==o?(p+=g.length-1,"="==(s=(u=e.tags[n.charAt(p+1)])?n.charAt(p+1):"_v")?(p=w(n,p),o=0):(u&&p++,o=2),h=p):f(v,n,p)?(c.push({tag:s,n:l(d),otag:g,ctag:v,i:"/"==s?h-g.length:p+v.length}),d="",p+=v.length-1,o=0,"{"==s&&("}}"==v?p++:"}"===(r=c[c.length-1]).n.substr(r.n.length-1)&&(r.n=r.n.substring(0,r.n.length-1)))):d+=n.charAt(p);return y(h,!0),c};var u={_t:!0,"\n":!0,$:!0,"/":!0};function d(t,n,i,r){var a,o=[],s=null,l=null;for(a=i[i.length-1];t.length>0;){if(l=t.shift(),a&&"<"==a.tag&&!(l.tag in u))throw new Error("Illegal content in < super tag.");if(e.tags[l.tag]<=e.tags.$||c(l,r))i.push(l),l.nodes=d(t,l.tag,i,r);else{if("/"==l.tag){if(0===i.length)throw new Error("Closing tag without opener: /"+l.n);if(s=i.pop(),l.n!=s.n&&!h(l.n,s.n,r))throw new Error("Nesting error: "+s.n+" vs. "+l.n);return s.end=l.i,o}"\n"==l.tag&&(l.last=0==t.length||"\n"==t[0].tag)}o.push(l)}if(i.length>0)throw new Error("missing closing tag: "+i.pop().n);return o}function c(e,t){for(var n=0,i=t.length;n<i;n++)if(t[n].o==e.n)return e.tag="#",!0}function h(e,t,n){for(var i=0,r=n.length;i<r;i++)if(n[i].c==e&&n[i].o==t)return!0}function p(e){var t=[];for(var n in e.partials)t.push('"'+g(n)+'":{name:"'+g(e.partials[n].name)+'", '+p(e.partials[n])+"}");return"partials: {"+t.join(",")+"}, subs: "+function(e){var t=[];for(var n in e)t.push('"'+g(n)+'": function(c,p,t,i) {'+e[n]+"}");return"{ "+t.join(",")+" }"}(e.subs)}e.stringify=function(t,n,i){return"{code: function (c,p,i) { "+e.wrapMain(t.code)+" },"+p(t)+"}"};var b=0;function g(e){return e.replace(a,"\\\\").replace(n,'\\"').replace(i,"\\n").replace(r,"\\r").replace(o,"\\u2028").replace(s,"\\u2029")}function v(e){return~e.indexOf(".")?"d":"f"}function m(e,t){var n="<"+(t.prefix||"")+e.n+b++;return t.partials[n]={name:e.n,partials:{}},t.code+='t.b(t.rp("'+g(n)+'",c,p,"'+(e.indent||"")+'"));',n}function y(e,t){t.code+="t.b(t.t(t."+v(e.n)+'("'+g(e.n)+'",c,p,0)));'}function w(e){return"t.b("+e+");"}e.generate=function(t,n,i){b=0;var r={code:"",subs:{},partials:{}};return e.walk(t,r),i.asString?this.stringify(r,n,i):this.makeTemplate(r,n,i)},e.wrapMain=function(e){return'var t=this;t.b(i=i||"");'+e+"return t.fl();"},e.template=e.Template,e.makeTemplate=function(e,t,n){var i=this.makePartials(e);return i.code=new Function("c","p","i",this.wrapMain(e.code)),new this.template(i,t,this,n)},e.makePartials=function(e){var t,n={subs:{},partials:e.partials,name:e.name};for(t in n.partials)n.partials[t]=this.makePartials(n.partials[t]);for(t in e.subs)n.subs[t]=new Function("c","p","t","i",e.subs[t]);return n},e.codegen={"#":function(t,n){n.code+="if(t.s(t."+v(t.n)+'("'+g(t.n)+'",c,p,1),c,p,0,'+t.i+","+t.end+',"'+t.otag+" "+t.ctag+'")){t.rs(c,p,function(c,p,t){',e.walk(t.nodes,n),n.code+="});c.pop();}"},"^":function(t,n){n.code+="if(!t.s(t."+v(t.n)+'("'+g(t.n)+'",c,p,1),c,p,1,0,0,"")){',e.walk(t.nodes,n),n.code+="};"},">":m,"<":function(t,n){var i={partials:{},code:"",subs:{},inPartial:!0};e.walk(t.nodes,i);var r=n.partials[m(t,n)];r.subs=i.subs,r.partials=i.partials},$:function(t,n){var i={subs:{},code:"",partials:n.partials,prefix:t.n};e.walk(t.nodes,i),n.subs[t.n]=i.code,n.inPartial||(n.code+='t.sub("'+g(t.n)+'",c,p,i);')},"\n":function(e,t){t.code+=w('"\\n"'+(e.last?"":" + i"))},_v:function(e,t){t.code+="t.b(t.v(t."+v(e.n)+'("'+g(e.n)+'",c,p,0)));'},_t:function(e,t){t.code+=w('"'+g(e.text)+'"')},"{":y,"&":y},e.walk=function(t,n){for(var i,r=0,a=t.length;r<a;r++)(i=e.codegen[t[r].tag])&&i(t[r],n);return n},e.parse=function(e,t,n){return d(e,0,[],(n=n||{}).sectionTags||[])},e.cache={},e.cacheKey=function(e,t){return[e,!!t.asString,!!t.disableLambda,t.delimiters,!!t.modelGet].join("||")},e.compile=function(t,n){n=n||{};var i=e.cacheKey(t,n),r=this.cache[i];if(r){var a=r.partials;for(var o in a)delete a[o].instance;return r}return r=this.generate(this.parse(this.scan(t,n.delimiters),t,n),t,n),this.cache[i]=r}}(t)},485:(e,t,n)=>{var i=n(397);i.Template=n(882).Template,i.template=i.Template,e.exports=i},882:(e,t)=>{!function(e){function t(e,t,n){var i;return t&&"object"==typeof t&&(void 0!==t[e]?i=t[e]:n&&t.get&&"function"==typeof t.get&&(i=t.get(e))),i}e.Template=function(e,t,n,i){e=e||{},this.r=e.code||this.r,this.c=n,this.options=i||{},this.text=t||"",this.partials=e.partials||{},this.subs=e.subs||{},this.buf=""},e.Template.prototype={r:function(e,t,n){return""},v:function(e){return e=l(e),s.test(e)?e.replace(n,"&amp;").replace(i,"&lt;").replace(r,"&gt;").replace(a,"&#39;").replace(o,"&quot;"):e},t:l,render:function(e,t,n){return this.ri([e],t||{},n)},ri:function(e,t,n){return this.r(e,t,n)},ep:function(e,t){var n=this.partials[e],i=t[n.name];if(n.instance&&n.base==i)return n.instance;if("string"==typeof i){if(!this.c)throw new Error("No compiler available.");i=this.c.compile(i,this.options)}if(!i)return null;if(this.partials[e].base=i,n.subs){for(key in t.stackText||(t.stackText={}),n.subs)t.stackText[key]||(t.stackText[key]=void 0!==this.activeSub&&t.stackText[this.activeSub]?t.stackText[this.activeSub]:this.text);i=function(e,t,n,i,r,a){function o(){}function s(){}var l;o.prototype=e,s.prototype=e.subs;var f=new o;for(l in f.subs=new s,f.subsText={},f.buf="",i=i||{},f.stackSubs=i,f.subsText=a,t)i[l]||(i[l]=t[l]);for(l in i)f.subs[l]=i[l];for(l in r=r||{},f.stackPartials=r,n)r[l]||(r[l]=n[l]);for(l in r)f.partials[l]=r[l];return f}(i,n.subs,n.partials,this.stackSubs,this.stackPartials,t.stackText)}return this.partials[e].instance=i,i},rp:function(e,t,n,i){var r=this.ep(e,n);return r?r.ri(t,n,i):""},rs:function(e,t,n){var i=e[e.length-1];if(f(i))for(var r=0;r<i.length;r++)e.push(i[r]),n(e,t,this),e.pop();else n(e,t,this)},s:function(e,t,n,i,r,a,o){var s;return(!f(e)||0!==e.length)&&("function"==typeof e&&(e=this.ms(e,t,n,i,r,a,o)),s=!!e,!i&&s&&t&&t.push("object"==typeof e?e:t[t.length-1]),s)},d:function(e,n,i,r){var a,o=e.split("."),s=this.f(o[0],n,i,r),l=this.options.modelGet,u=null;if("."===e&&f(n[n.length-2]))s=n[n.length-1];else for(var d=1;d<o.length;d++)void 0!==(a=t(o[d],s,l))?(u=s,s=a):s="";return!(r&&!s)&&(r||"function"!=typeof s||(n.push(u),s=this.mv(s,n,i),n.pop()),s)},f:function(e,n,i,r){for(var a=!1,o=!1,s=this.options.modelGet,l=n.length-1;l>=0;l--)if(void 0!==(a=t(e,n[l],s))){o=!0;break}return o?(r||"function"!=typeof a||(a=this.mv(a,n,i)),a):!r&&""},ls:function(e,t,n,i,r){var a=this.options.delimiters;return this.options.delimiters=r,this.b(this.ct(l(e.call(t,i)),t,n)),this.options.delimiters=a,!1},ct:function(e,t,n){if(this.options.disableLambda)throw new Error("Lambda features disabled.");return this.c.compile(e,this.options).render(t,n)},b:function(e){this.buf+=e},fl:function(){var e=this.buf;return this.buf="",e},ms:function(e,t,n,i,r,a,o){var s,l=t[t.length-1],f=e.call(l);return"function"==typeof f?!!i||(s=this.activeSub&&this.subsText&&this.subsText[this.activeSub]?this.subsText[this.activeSub]:this.text,this.ls(f,l,n,s.substring(r,a),o)):f},mv:function(e,t,n){var i=t[t.length-1],r=e.call(i);return"function"==typeof r?this.ct(l(r.call(i)),i,n):r},sub:function(e,t,n,i){var r=this.subs[e];r&&(this.activeSub=e,r(t,n,this,i),this.activeSub=!1)}};var n=/&/g,i=/</g,r=/>/g,a=/\'/g,o=/\"/g,s=/[&<>\"\']/;function l(e){return String(null==e?"":e)}var f=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}}(t)},468:function(e,t,n){"use strict";var i=this&&this.__spreadArray||function(e,t,n){if(n||2===arguments.length)for(var i,r=0,a=t.length;r<a;r++)!i&&r in t||(i||(i=Array.prototype.slice.call(t,0,r)),i[r]=t[r]);return e.concat(i||Array.prototype.slice.call(t))};Object.defineProperty(t,"__esModule",{value:!0}),t.parse=void 0;var r=n(699),a=n(593);function o(e,t){var n=e.split(".");return n.length>1?n[n.length-1]:t}function s(e,t){return t.reduce((function(t,n){return t||e.startsWith(n)}),!1)}var l=["a/","b/","i/","w/","c/","o/"];function f(e,t,n){var r=void 0!==n?i(i([],l,!0),[n],!1):l,o=((t?new RegExp("^"+(0,a.escapeForRegExp)(t)+' "?(.+?)"?$'):new RegExp('^"?(.+?)"?$')).exec(e)||[])[1],s=void 0===o?"":o,f=r.find((function(e){return 0===s.indexOf(e)}));return(f?s.slice(f.length):s).replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [+-]\d{4}.*$/,"")}t.parse=function(e,t){void 0===t&&(t={});var n=[],i=null,a=null,l=null,u=null,d=null,c=null,h=null,p="--- ",b="+++ ",g="@@",v=/^old mode (\d{6})/,m=/^new mode (\d{6})/,y=/^deleted file mode (\d{6})/,w=/^new file mode (\d{6})/,L=/^copy from "?(.+)"?/,S=/^copy to "?(.+)"?/,x=/^rename from "?(.+)"?/,C=/^rename to "?(.+)"?/,T=/^similarity index (\d+)%/,_=/^dissimilarity index (\d+)%/,N=/^index ([\da-z]+)\.\.([\da-z]+)\s*(\d{6})?/,O=/^Binary files (.*) and (.*) differ/,P=/^GIT binary patch/,j=/^index ([\da-z]+),([\da-z]+)\.\.([\da-z]+)/,E=/^mode (\d{6}),(\d{6})\.\.(\d{6})/,M=/^new file mode (\d{6})/,H=/^deleted file mode (\d{6}),(\d{6})/,k=e.replace(/\\ No newline at end of file/g,"").replace(/\r\n?/g,"\n").split("\n");function F(){null!==a&&null!==i&&(i.blocks.push(a),a=null)}function D(){null!==i&&(i.oldName||null===c||(i.oldName=c),i.newName||null===h||(i.newName=h),i.newName&&(n.push(i),i=null)),c=null,h=null}function I(){F(),D(),i={blocks:[],deletedLines:0,addedLines:0}}function A(e){var t;F(),null!==i&&((t=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@.*/.exec(e))?(i.isCombined=!1,l=parseInt(t[1],10),d=parseInt(t[2],10)):(t=/^@@@ -(\d+)(?:,\d+)? -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@@.*/.exec(e))?(i.isCombined=!0,l=parseInt(t[1],10),u=parseInt(t[2],10),d=parseInt(t[3],10)):(e.startsWith(g)&&console.error("Failed to parse lines, starting in 0!"),l=0,d=0,i.isCombined=!1)),a={lines:[],oldStartLine:l,oldStartLine2:u,newStartLine:d,header:e}}return k.forEach((function(e,u){if(e&&!e.startsWith("*")){var F,D=k[u-1],W=k[u+1],R=k[u+2];if(e.startsWith("diff")){if(I(),(F=/^diff --git "?([a-ciow]\/.+)"? "?([a-ciow]\/.+)"?/.exec(e))&&(c=f(F[1],void 0,t.dstPrefix),h=f(F[2],void 0,t.srcPrefix)),null===i)throw new Error("Where is my file !!!");i.isGitDiff=!0}else if((!i||!i.isGitDiff&&i&&e.startsWith(p)&&W.startsWith(b)&&R.startsWith(g))&&I(),!(null==i?void 0:i.isTooBig)){if(i&&("number"==typeof t.diffMaxChanges&&i.addedLines+i.deletedLines>t.diffMaxChanges||"number"==typeof t.diffMaxLineLength&&e.length>t.diffMaxLineLength))return i.isTooBig=!0,i.addedLines=0,i.deletedLines=0,i.blocks=[],a=null,void A("function"==typeof t.diffTooBigMessage?t.diffTooBigMessage(n.length):"Diff too big to be displayed");if(e.startsWith(p)&&W.startsWith(b)||e.startsWith(b)&&D.startsWith(p)){if(i&&!i.oldName&&e.startsWith("--- ")&&(F=function(e,t){return f(e,"---",t)}(e,t.srcPrefix)))return i.oldName=F,void(i.language=o(i.oldName,i.language));if(i&&!i.newName&&e.startsWith("+++ ")&&(F=function(e,t){return f(e,"+++",t)}(e,t.dstPrefix)))return i.newName=F,void(i.language=o(i.newName,i.language))}if(i&&(e.startsWith(g)||i.isGitDiff&&i.oldName&&i.newName&&!a))A(e);else if(a&&(e.startsWith("+")||e.startsWith("-")||e.startsWith(" ")))!function(e){if(null!==i&&null!==a&&null!==l&&null!==d){var t={content:e},n=i.isCombined?["+ "," +","++"]:["+"],o=i.isCombined?["- "," -","--"]:["-"];s(e,n)?(i.addedLines++,t.type=r.LineType.INSERT,t.oldNumber=void 0,t.newNumber=d++):s(e,o)?(i.deletedLines++,t.type=r.LineType.DELETE,t.oldNumber=l++,t.newNumber=void 0):(t.type=r.LineType.CONTEXT,t.oldNumber=l++,t.newNumber=d++),a.lines.push(t)}}(e);else{var B=!function(e,t){for(var n=t;n<k.length-3;){if(e.startsWith("diff"))return!1;if(k[n].startsWith(p)&&k[n+1].startsWith(b)&&k[n+2].startsWith(g))return!0;n++}return!1}(e,u);if(null===i)throw new Error("Where is my file !!!");(F=v.exec(e))?i.oldMode=F[1]:(F=m.exec(e))?i.newMode=F[1]:(F=y.exec(e))?(i.deletedFileMode=F[1],i.isDeleted=!0):(F=w.exec(e))?(i.newFileMode=F[1],i.isNew=!0):(F=L.exec(e))?(B&&(i.oldName=F[1]),i.isCopy=!0):(F=S.exec(e))?(B&&(i.newName=F[1]),i.isCopy=!0):(F=x.exec(e))?(B&&(i.oldName=F[1]),i.isRename=!0):(F=C.exec(e))?(B&&(i.newName=F[1]),i.isRename=!0):(F=O.exec(e))?(i.isBinary=!0,i.oldName=f(F[1],void 0,t.srcPrefix),i.newName=f(F[2],void 0,t.dstPrefix),A("Binary file")):P.test(e)?(i.isBinary=!0,A(e)):(F=T.exec(e))?i.unchangedPercentage=parseInt(F[1],10):(F=_.exec(e))?i.changedPercentage=parseInt(F[1],10):(F=N.exec(e))?(i.checksumBefore=F[1],i.checksumAfter=F[2],F[3]&&(i.mode=F[3])):(F=j.exec(e))?(i.checksumBefore=[F[2],F[3]],i.checksumAfter=F[1]):(F=E.exec(e))?(i.oldMode=[F[2],F[3]],i.newMode=F[1]):(F=M.exec(e))?(i.newFileMode=F[1],i.isNew=!0):(F=H.exec(e))&&(i.deletedFileMode=F[1],i.isDeleted=!0)}}}})),F(),D(),n}},979:function(e,t,n){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&i(t,e,n);return r(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.defaultTemplates=void 0;var o=a(n(485));t.defaultTemplates={},t.defaultTemplates["file-summary-line"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<li class="d2h-file-list-line">'),i.b("\n"+n),i.b('    <span class="d2h-file-name-wrapper">'),i.b("\n"+n),i.b(i.rp("<fileIcon0",e,t,"      ")),i.b('      <a href="#'),i.b(i.v(i.f("fileHtmlId",e,t,0))),i.b('" class="d2h-file-name">'),i.b(i.v(i.f("fileName",e,t,0))),i.b("</a>"),i.b("\n"+n),i.b('      <span class="d2h-file-stats">'),i.b("\n"+n),i.b('          <span class="d2h-lines-added">'),i.b(i.v(i.f("addedLines",e,t,0))),i.b("</span>"),i.b("\n"+n),i.b('          <span class="d2h-lines-deleted">'),i.b(i.v(i.f("deletedLines",e,t,0))),i.b("</span>"),i.b("\n"+n),i.b("      </span>"),i.b("\n"+n),i.b("    </span>"),i.b("\n"+n),i.b("</li>"),i.fl()},partials:{"<fileIcon0":{name:"fileIcon",partials:{},subs:{}}},subs:{}}),t.defaultTemplates["file-summary-wrapper"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<div class="d2h-file-list-wrapper">'),i.b("\n"+n),i.b('    <div class="d2h-file-list-header">'),i.b("\n"+n),i.b('        <span class="d2h-file-list-title">Files changed ('),i.b(i.v(i.f("filesNumber",e,t,0))),i.b(")</span>"),i.b("\n"+n),i.b('        <a class="d2h-file-switch d2h-hide">hide</a>'),i.b("\n"+n),i.b('        <a class="d2h-file-switch d2h-show">show</a>'),i.b("\n"+n),i.b("    </div>"),i.b("\n"+n),i.b('    <ol class="d2h-file-list">'),i.b("\n"+n),i.b("    "),i.b(i.t(i.f("files",e,t,0))),i.b("\n"+n),i.b("    </ol>"),i.b("\n"+n),i.b("</div>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["generic-block-header"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b("<tr>"),i.b("\n"+n),i.b('    <td class="'),i.b(i.v(i.f("lineClass",e,t,0))),i.b(" "),i.b(i.v(i.d("CSSLineClass.INFO",e,t,0))),i.b('"></td>'),i.b("\n"+n),i.b('    <td class="'),i.b(i.v(i.d("CSSLineClass.INFO",e,t,0))),i.b('">'),i.b("\n"+n),i.b('        <div class="'),i.b(i.v(i.f("contentClass",e,t,0))),i.b('">'),i.b(i.t(i.f("blockHeader",e,t,0))),i.b("</div>"),i.b("\n"+n),i.b("    </td>"),i.b("\n"+n),i.b("</tr>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["generic-empty-diff"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b("<tr>"),i.b("\n"+n),i.b('    <td class="'),i.b(i.v(i.d("CSSLineClass.INFO",e,t,0))),i.b('">'),i.b("\n"+n),i.b('        <div class="'),i.b(i.v(i.f("contentClass",e,t,0))),i.b('">'),i.b("\n"+n),i.b("            File without changes"),i.b("\n"+n),i.b("        </div>"),i.b("\n"+n),i.b("    </td>"),i.b("\n"+n),i.b("</tr>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["generic-file-path"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<span class="d2h-file-name-wrapper">'),i.b("\n"+n),i.b(i.rp("<fileIcon0",e,t,"    ")),i.b('    <span class="d2h-file-name">'),i.b(i.v(i.f("fileDiffName",e,t,0))),i.b("</span>"),i.b("\n"+n),i.b(i.rp("<fileTag1",e,t,"    ")),i.b("</span>"),i.b("\n"+n),i.b('<label class="d2h-file-collapse">'),i.b("\n"+n),i.b('    <input class="d2h-file-collapse-input" type="checkbox" name="viewed" value="viewed">'),i.b("\n"+n),i.b("    Viewed"),i.b("\n"+n),i.b("</label>"),i.fl()},partials:{"<fileIcon0":{name:"fileIcon",partials:{},subs:{}},"<fileTag1":{name:"fileTag",partials:{},subs:{}}},subs:{}}),t.defaultTemplates["generic-line"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b("<tr>"),i.b("\n"+n),i.b('    <td class="'),i.b(i.v(i.f("lineClass",e,t,0))),i.b(" "),i.b(i.v(i.f("type",e,t,0))),i.b('">'),i.b("\n"+n),i.b("      "),i.b(i.t(i.f("lineNumber",e,t,0))),i.b("\n"+n),i.b("    </td>"),i.b("\n"+n),i.b('    <td class="'),i.b(i.v(i.f("type",e,t,0))),i.b('">'),i.b("\n"+n),i.b('        <div class="'),i.b(i.v(i.f("contentClass",e,t,0))),i.b('">'),i.b("\n"+n),i.s(i.f("prefix",e,t,1),e,t,0,162,238,"{{ }}")&&(i.rs(e,t,(function(e,t,i){i.b('            <span class="d2h-code-line-prefix">'),i.b(i.t(i.f("prefix",e,t,0))),i.b("</span>"),i.b("\n"+n)})),e.pop()),i.s(i.f("prefix",e,t,1),e,t,1,0,0,"")||(i.b('            <span class="d2h-code-line-prefix">&nbsp;</span>'),i.b("\n"+n)),i.s(i.f("content",e,t,1),e,t,0,371,445,"{{ }}")&&(i.rs(e,t,(function(e,t,i){i.b('            <span class="d2h-code-line-ctn">'),i.b(i.t(i.f("content",e,t,0))),i.b("</span>"),i.b("\n"+n)})),e.pop()),i.s(i.f("content",e,t,1),e,t,1,0,0,"")||(i.b('            <span class="d2h-code-line-ctn"><br></span>'),i.b("\n"+n)),i.b("        </div>"),i.b("\n"+n),i.b("    </td>"),i.b("\n"+n),i.b("</tr>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["generic-wrapper"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<div class="d2h-wrapper">'),i.b("\n"+n),i.b("    "),i.b(i.t(i.f("content",e,t,0))),i.b("\n"+n),i.b("</div>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["icon-file-added"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<svg aria-hidden="true" class="d2h-icon d2h-added" height="16" title="added" version="1.1" viewBox="0 0 14 16"'),i.b("\n"+n),i.b('     width="14">'),i.b("\n"+n),i.b('    <path d="M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z"></path>'),i.b("\n"+n),i.b("</svg>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["icon-file-changed"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<svg aria-hidden="true" class="d2h-icon d2h-changed" height="16" title="modified" version="1.1"'),i.b("\n"+n),i.b('     viewBox="0 0 14 16" width="14">'),i.b("\n"+n),i.b('    <path d="M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z"></path>'),i.b("\n"+n),i.b("</svg>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["icon-file-deleted"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<svg aria-hidden="true" class="d2h-icon d2h-deleted" height="16" title="removed" version="1.1"'),i.b("\n"+n),i.b('     viewBox="0 0 14 16" width="14">'),i.b("\n"+n),i.b('    <path d="M13 1H1C0.45 1 0 1.45 0 2v12c0 0.55 0.45 1 1 1h12c0.55 0 1-0.45 1-1V2c0-0.55-0.45-1-1-1z m0 13H1V2h12v12zM11 9H3V7h8v2z"></path>'),i.b("\n"+n),i.b("</svg>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["icon-file-renamed"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<svg aria-hidden="true" class="d2h-icon d2h-moved" height="16" title="renamed" version="1.1"'),i.b("\n"+n),i.b('     viewBox="0 0 14 16" width="14">'),i.b("\n"+n),i.b('    <path d="M6 9H3V7h3V4l5 4-5 4V9z m8-7v12c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h12c0.55 0 1 0.45 1 1z m-1 0H1v12h12V2z"></path>'),i.b("\n"+n),i.b("</svg>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["icon-file"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<svg aria-hidden="true" class="d2h-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12">'),i.b("\n"+n),i.b('    <path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>'),i.b("\n"+n),i.b("</svg>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["line-by-line-file-diff"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<div id="'),i.b(i.v(i.f("fileHtmlId",e,t,0))),i.b('" class="d2h-file-wrapper" data-lang="'),i.b(i.v(i.d("file.language",e,t,0))),i.b('">'),i.b("\n"+n),i.b('    <div class="d2h-file-header">'),i.b("\n"+n),i.b("    "),i.b(i.t(i.f("filePath",e,t,0))),i.b("\n"+n),i.b("    </div>"),i.b("\n"+n),i.b('    <div class="d2h-file-diff">'),i.b("\n"+n),i.b('        <div class="d2h-code-wrapper">'),i.b("\n"+n),i.b('            <table class="d2h-diff-table">'),i.b("\n"+n),i.b('                <tbody class="d2h-diff-tbody">'),i.b("\n"+n),i.b("                "),i.b(i.t(i.f("diffs",e,t,0))),i.b("\n"+n),i.b("                </tbody>"),i.b("\n"+n),i.b("            </table>"),i.b("\n"+n),i.b("        </div>"),i.b("\n"+n),i.b("    </div>"),i.b("\n"+n),i.b("</div>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["line-by-line-numbers"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<div class="line-num1">'),i.b(i.v(i.f("oldNumber",e,t,0))),i.b("</div>"),i.b("\n"+n),i.b('<div class="line-num2">'),i.b(i.v(i.f("newNumber",e,t,0))),i.b("</div>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["side-by-side-file-diff"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<div id="'),i.b(i.v(i.f("fileHtmlId",e,t,0))),i.b('" class="d2h-file-wrapper" data-lang="'),i.b(i.v(i.d("file.language",e,t,0))),i.b('">'),i.b("\n"+n),i.b('    <div class="d2h-file-header">'),i.b("\n"+n),i.b("      "),i.b(i.t(i.f("filePath",e,t,0))),i.b("\n"+n),i.b("    </div>"),i.b("\n"+n),i.b('    <div class="d2h-files-diff">'),i.b("\n"+n),i.b('        <div class="d2h-file-side-diff">'),i.b("\n"+n),i.b('            <div class="d2h-code-wrapper">'),i.b("\n"+n),i.b('                <table class="d2h-diff-table">'),i.b("\n"+n),i.b('                    <tbody class="d2h-diff-tbody">'),i.b("\n"+n),i.b("                    "),i.b(i.t(i.d("diffs.left",e,t,0))),i.b("\n"+n),i.b("                    </tbody>"),i.b("\n"+n),i.b("                </table>"),i.b("\n"+n),i.b("            </div>"),i.b("\n"+n),i.b("        </div>"),i.b("\n"+n),i.b('        <div class="d2h-file-side-diff">'),i.b("\n"+n),i.b('            <div class="d2h-code-wrapper">'),i.b("\n"+n),i.b('                <table class="d2h-diff-table">'),i.b("\n"+n),i.b('                    <tbody class="d2h-diff-tbody">'),i.b("\n"+n),i.b("                    "),i.b(i.t(i.d("diffs.right",e,t,0))),i.b("\n"+n),i.b("                    </tbody>"),i.b("\n"+n),i.b("                </table>"),i.b("\n"+n),i.b("            </div>"),i.b("\n"+n),i.b("        </div>"),i.b("\n"+n),i.b("    </div>"),i.b("\n"+n),i.b("</div>"),i.fl()},partials:{},subs:{}}),t.defaultTemplates["tag-file-added"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<span class="d2h-tag d2h-added d2h-added-tag">ADDED</span>'),i.fl()},partials:{},subs:{}}),t.defaultTemplates["tag-file-changed"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span>'),i.fl()},partials:{},subs:{}}),t.defaultTemplates["tag-file-deleted"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<span class="d2h-tag d2h-deleted d2h-deleted-tag">DELETED</span>'),i.fl()},partials:{},subs:{}}),t.defaultTemplates["tag-file-renamed"]=new o.Template({code:function(e,t,n){var i=this;return i.b(n=n||""),i.b('<span class="d2h-tag d2h-moved d2h-moved-tag">RENAMED</span>'),i.fl()},partials:{},subs:{}})},834:function(e,t,n){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,i=arguments.length;n<i;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)},r=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&r(t,e,n);return a(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.html=t.parse=t.defaultDiff2HtmlConfig=void 0;var l=o(n(468)),f=o(n(479)),u=o(n(378)),d=o(n(170)),c=n(699),h=s(n(63));t.defaultDiff2HtmlConfig=i(i(i({},u.defaultLineByLineRendererConfig),d.defaultSideBySideRendererConfig),{outputFormat:c.OutputFormatType.LINE_BY_LINE,drawFileList:!0}),t.parse=function(e,n){return void 0===n&&(n={}),l.parse(e,i(i({},t.defaultDiff2HtmlConfig),n))},t.html=function(e,n){void 0===n&&(n={});var r=i(i({},t.defaultDiff2HtmlConfig),n),a="string"==typeof e?l.parse(e,r):e,o=new h.default(r);return(r.drawFileList?f.render(a,o):"")+("side-by-side"===r.outputFormat?new d.default(o,r).render(a):new u.default(o,r).render(a))}},479:function(e,t,n){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),r=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&i(t,e,n);return r(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.render=void 0;var o=a(n(741)),s="file-summary";t.render=function(e,t){var n=e.map((function(e){return t.render(s,"line",{fileHtmlId:o.getHtmlId(e),oldName:e.oldName,newName:e.newName,fileName:o.filenameDiff(e),deletedLines:"-"+e.deletedLines,addedLines:"+"+e.addedLines},{fileIcon:t.template("icon",o.getFileIcon(e))})})).join("\n");return t.render(s,"wrapper",{filesNumber:e.length,files:n})}},63:function(e,t,n){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,i=arguments.length;n<i;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)},r=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&r(t,e,n);return a(t,e),t};Object.defineProperty(t,"__esModule",{value:!0});var s=o(n(485)),l=n(979),f=function(){function e(e){var t=e.compiledTemplates,n=void 0===t?{}:t,r=e.rawTemplates,a=void 0===r?{}:r,o=Object.entries(a).reduce((function(e,t){var n,r=t[0],a=t[1],o=s.compile(a,{asString:!1});return i(i({},e),((n={})[r]=o,n))}),{});this.preCompiledTemplates=i(i(i({},l.defaultTemplates),n),o)}return e.compile=function(e){return s.compile(e,{asString:!1})},e.prototype.render=function(e,t,n,i,r){var a=this.templateKey(e,t);try{return this.preCompiledTemplates[a].render(n,i,r)}catch(e){throw new Error("Could not find template to render '"+a+"'")}},e.prototype.template=function(e,t){return this.preCompiledTemplates[this.templateKey(e,t)]},e.prototype.templateKey=function(e,t){return e+"-"+t},e}();t.default=f},378:function(e,t,n){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,i=arguments.length;n<i;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)},r=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&r(t,e,n);return a(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.defaultLineByLineRendererConfig=void 0;var s=o(n(483)),l=o(n(741)),f=n(699);t.defaultLineByLineRendererConfig=i(i({},l.defaultRenderConfig),{renderNothingWhenEmpty:!1,matchingMaxComparisons:2500,maxLineSizeInBlockForComparison:200});var u="generic",d="line-by-line",c=function(){function e(e,n){void 0===n&&(n={}),this.hoganUtils=e,this.config=i(i({},t.defaultLineByLineRendererConfig),n)}return e.prototype.render=function(e){var t=this,n=e.map((function(e){var n;return n=e.blocks.length?t.generateFileHtml(e):t.generateEmptyDiff(),t.makeFileDiffHtml(e,n)})).join("\n");return this.hoganUtils.render(u,"wrapper",{content:n})},e.prototype.makeFileDiffHtml=function(e,t){if(this.config.renderNothingWhenEmpty&&Array.isArray(e.blocks)&&0===e.blocks.length)return"";var n=this.hoganUtils.template(d,"file-diff"),i=this.hoganUtils.template(u,"file-path"),r=this.hoganUtils.template("icon","file"),a=this.hoganUtils.template("tag",l.getFileIcon(e));return n.render({file:e,fileHtmlId:l.getHtmlId(e),diffs:t,filePath:i.render({fileDiffName:l.filenameDiff(e)},{fileIcon:r,fileTag:a})})},e.prototype.generateEmptyDiff=function(){return this.hoganUtils.render(u,"empty-diff",{contentClass:"d2h-code-line",CSSLineClass:l.CSSLineClass})},e.prototype.generateFileHtml=function(e){var t=this,n=s.newMatcherFn(s.newDistanceFn((function(t){return l.deconstructLine(t.content,e.isCombined).content})));return e.blocks.map((function(i){var r=t.hoganUtils.render(u,"block-header",{CSSLineClass:l.CSSLineClass,blockHeader:e.isTooBig?i.header:l.escapeForHtml(i.header),lineClass:"d2h-code-linenumber",contentClass:"d2h-code-line"});return t.applyLineGroupping(i).forEach((function(i){var a=i[0],o=i[1],s=i[2];if(o.length&&s.length&&!a.length)t.applyRematchMatching(o,s,n).map((function(n){var i=n[0],a=n[1],o=t.processChangedLines(e.isCombined,i,a),s=o.left,l=o.right;r+=s,r+=l}));else if(a.length)a.forEach((function(n){var i=l.deconstructLine(n.content,e.isCombined),a=i.prefix,o=i.content;r+=t.generateSingleLineHtml({type:l.CSSLineClass.CONTEXT,prefix:a,content:o,oldNumber:n.oldNumber,newNumber:n.newNumber})}));else if(o.length||s.length){var f=t.processChangedLines(e.isCombined,o,s),u=f.left,d=f.right;r+=u,r+=d}else console.error("Unknown state reached while processing groups of lines",a,o,s)})),r})).join("\n")},e.prototype.applyLineGroupping=function(e){for(var t=[],n=[],i=[],r=0;r<e.lines.length;r++){var a=e.lines[r];(a.type!==f.LineType.INSERT&&i.length||a.type===f.LineType.CONTEXT&&n.length>0)&&(t.push([[],n,i]),n=[],i=[]),a.type===f.LineType.CONTEXT?t.push([[a],[],[]]):a.type===f.LineType.INSERT&&0===n.length?t.push([[],[],[a]]):a.type===f.LineType.INSERT&&n.length>0?i.push(a):a.type===f.LineType.DELETE&&n.push(a)}return(n.length||i.length)&&(t.push([[],n,i]),n=[],i=[]),t},e.prototype.applyRematchMatching=function(e,t,n){var i=e.length*t.length,r=Math.max.apply(null,[0].concat(e.concat(t).map((function(e){return e.content.length}))));return i<this.config.matchingMaxComparisons&&r<this.config.maxLineSizeInBlockForComparison&&("lines"===this.config.matching||"words"===this.config.matching)?n(e,t):[[e,t]]},e.prototype.processChangedLines=function(e,t,n){for(var r={right:"",left:""},a=Math.max(t.length,n.length),o=0;o<a;o++){var s=t[o],f=n[o],u=void 0!==s&&void 0!==f?l.diffHighlight(s.content,f.content,e,this.config):void 0,d=void 0!==s&&void 0!==s.oldNumber?i(i({},void 0!==u?{prefix:u.oldLine.prefix,content:u.oldLine.content,type:l.CSSLineClass.DELETE_CHANGES}:i(i({},l.deconstructLine(s.content,e)),{type:l.toCSSClass(s.type)})),{oldNumber:s.oldNumber,newNumber:s.newNumber}):void 0,c=void 0!==f&&void 0!==f.newNumber?i(i({},void 0!==u?{prefix:u.newLine.prefix,content:u.newLine.content,type:l.CSSLineClass.INSERT_CHANGES}:i(i({},l.deconstructLine(f.content,e)),{type:l.toCSSClass(f.type)})),{oldNumber:f.oldNumber,newNumber:f.newNumber}):void 0,h=this.generateLineHtml(d,c),p=h.left,b=h.right;r.left+=p,r.right+=b}return r},e.prototype.generateLineHtml=function(e,t){return{left:this.generateSingleLineHtml(e),right:this.generateSingleLineHtml(t)}},e.prototype.generateSingleLineHtml=function(e){if(void 0===e)return"";var t=this.hoganUtils.render(d,"numbers",{oldNumber:e.oldNumber||"",newNumber:e.newNumber||""});return this.hoganUtils.render(u,"line",{type:e.type,lineClass:"d2h-code-linenumber",contentClass:"d2h-code-line",prefix:" "===e.prefix?"&nbsp;":e.prefix,content:e.content,lineNumber:t})},e}();t.default=c},483:(e,t)=>{"use strict";function n(e,t){if(0===e.length)return t.length;if(0===t.length)return e.length;var n,i,r=[];for(n=0;n<=t.length;n++)r[n]=[n];for(i=0;i<=e.length;i++)r[0][i]=i;for(n=1;n<=t.length;n++)for(i=1;i<=e.length;i++)t.charAt(n-1)===e.charAt(i-1)?r[n][i]=r[n-1][i-1]:r[n][i]=Math.min(r[n-1][i-1]+1,Math.min(r[n][i-1]+1,r[n-1][i]+1));return r[t.length][e.length]}Object.defineProperty(t,"__esModule",{value:!0}),t.newMatcherFn=t.newDistanceFn=t.levenshtein=void 0,t.levenshtein=n,t.newDistanceFn=function(e){return function(t,i){var r=e(t).trim(),a=e(i).trim();return n(r,a)/(r.length+a.length)}},t.newMatcherFn=function(e){return function t(n,i,r,a){void 0===r&&(r=0),void 0===a&&(a=new Map);var o=function(t,n,i){void 0===i&&(i=new Map);for(var r,a=1/0,o=0;o<t.length;++o)for(var s=0;s<n.length;++s){var l=JSON.stringify([t[o],n[s]]),f=void 0;i.has(l)&&(f=i.get(l))||(f=e(t[o],n[s]),i.set(l,f)),f<a&&(r={indexA:o,indexB:s,score:a=f})}return r}(n,i,a);if(!o||n.length+i.length<3)return[[n,i]];var s=n.slice(0,o.indexA),l=i.slice(0,o.indexB),f=[n[o.indexA]],u=[i[o.indexB]],d=o.indexA+1,c=o.indexB+1,h=n.slice(d),p=i.slice(c),b=t(s,l,r+1,a),g=t(f,u,r+1,a),v=t(h,p,r+1,a),m=g;return(o.indexA>0||o.indexB>0)&&(m=b.concat(m)),(n.length>d||i.length>c)&&(m=m.concat(v)),m}}},741:function(e,t,n){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,i=arguments.length;n<i;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)},r=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&r(t,e,n);return a(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.diffHighlight=t.getFileIcon=t.getHtmlId=t.filenameDiff=t.deconstructLine=t.escapeForHtml=t.toCSSClass=t.defaultRenderConfig=t.CSSLineClass=void 0;var s=o(n(785)),l=n(593),f=o(n(483)),u=n(699);t.CSSLineClass={INSERTS:"d2h-ins",DELETES:"d2h-del",CONTEXT:"d2h-cntx",INFO:"d2h-info",INSERT_CHANGES:"d2h-ins d2h-change",DELETE_CHANGES:"d2h-del d2h-change"},t.defaultRenderConfig={matching:u.LineMatchingType.NONE,matchWordsThreshold:.25,maxLineLengthHighlight:1e4,diffStyle:u.DiffStyleType.WORD};var d="/",c=f.newDistanceFn((function(e){return e.value})),h=f.newMatcherFn(c);function p(e){return-1!==e.indexOf("dev/null")}function b(e){return e.replace(/(<del[^>]*>((.|\n)*?)<\/del>)/g,"")}function g(e){return e.slice(0).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")}function v(e,t,n){void 0===n&&(n=!0);var i=function(e){return e?2:1}(t);return{prefix:e.substring(0,i),content:n?g(e.substring(i)):e.substring(i)}}function m(e){var t=(0,l.unifyPath)(e.oldName),n=(0,l.unifyPath)(e.newName);if(t===n||p(t)||p(n))return p(n)?t:n;for(var i=[],r=[],a=t.split(d),o=n.split(d),s=0,f=a.length-1,u=o.length-1;s<f&&s<u&&a[s]===o[s];)i.push(o[s]),s+=1;for(;f>s&&u>s&&a[f]===o[u];)r.unshift(o[u]),f-=1,u-=1;var c=i.join(d),h=r.join(d),b=a.slice(s,f+1).join(d),g=o.slice(s,u+1).join(d);return c.length&&h.length?c+d+"{"+b+" → "+g+"}"+d+h:c.length?c+d+"{"+b+" → "+g+"}":h.length?"{"+b+" → "+g+"}"+d+h:t+" → "+n}t.toCSSClass=function(e){switch(e){case u.LineType.CONTEXT:return t.CSSLineClass.CONTEXT;case u.LineType.INSERT:return t.CSSLineClass.INSERTS;case u.LineType.DELETE:return t.CSSLineClass.DELETES}},t.escapeForHtml=g,t.deconstructLine=v,t.filenameDiff=m,t.getHtmlId=function(e){return"d2h-"+(0,l.hashCode)(m(e)).toString().slice(-6)},t.getFileIcon=function(e){var t="file-changed";return e.isRename||e.isCopy?t="file-renamed":e.isNew?t="file-added":e.isDeleted?t="file-deleted":e.newName!==e.oldName&&(t="file-renamed"),t},t.diffHighlight=function(e,n,r,a){void 0===a&&(a={});var o=i(i({},t.defaultRenderConfig),a),l=o.matching,f=o.maxLineLengthHighlight,u=o.matchWordsThreshold,d=o.diffStyle,p=v(e,r,!1),m=v(n,r,!1);if(p.content.length>f||m.content.length>f)return{oldLine:{prefix:p.prefix,content:g(p.content)},newLine:{prefix:m.prefix,content:g(m.content)}};var y="char"===d?s.diffChars(p.content,m.content):s.diffWordsWithSpace(p.content,m.content),w=[];if("word"===d&&"words"===l){var L=y.filter((function(e){return e.removed})),S=y.filter((function(e){return e.added}));h(S,L).forEach((function(e){1===e[0].length&&1===e[1].length&&c(e[0][0],e[1][0])<u&&(w.push(e[0][0]),w.push(e[1][0]))}))}var x,C=y.reduce((function(e,t){var n=t.added?"ins":t.removed?"del":null,i=w.indexOf(t)>-1?' class="d2h-change"':"",r=g(t.value);return null!==n?e+"<"+n+i+">"+r+"</"+n+">":""+e+r}),"");return{oldLine:{prefix:p.prefix,content:(x=C,x.replace(/(<ins[^>]*>((.|\n)*?)<\/ins>)/g,""))},newLine:{prefix:m.prefix,content:b(C)}}}},170:function(e,t,n){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(e){for(var t,n=1,i=arguments.length;n<i;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,arguments)},r=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,i){void 0===i&&(i=n),e[i]=t[n]}),a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&r(t,e,n);return a(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.defaultSideBySideRendererConfig=void 0;var s=o(n(483)),l=o(n(741)),f=n(699);t.defaultSideBySideRendererConfig=i(i({},l.defaultRenderConfig),{renderNothingWhenEmpty:!1,matchingMaxComparisons:2500,maxLineSizeInBlockForComparison:200});var u="generic",d=function(){function e(e,n){void 0===n&&(n={}),this.hoganUtils=e,this.config=i(i({},t.defaultSideBySideRendererConfig),n)}return e.prototype.render=function(e){var t=this,n=e.map((function(e){var n;return n=e.blocks.length?t.generateFileHtml(e):t.generateEmptyDiff(),t.makeFileDiffHtml(e,n)})).join("\n");return this.hoganUtils.render(u,"wrapper",{content:n})},e.prototype.makeFileDiffHtml=function(e,t){if(this.config.renderNothingWhenEmpty&&Array.isArray(e.blocks)&&0===e.blocks.length)return"";var n=this.hoganUtils.template("side-by-side","file-diff"),i=this.hoganUtils.template(u,"file-path"),r=this.hoganUtils.template("icon","file"),a=this.hoganUtils.template("tag",l.getFileIcon(e));return n.render({file:e,fileHtmlId:l.getHtmlId(e),diffs:t,filePath:i.render({fileDiffName:l.filenameDiff(e)},{fileIcon:r,fileTag:a})})},e.prototype.generateEmptyDiff=function(){return{right:"",left:this.hoganUtils.render(u,"empty-diff",{contentClass:"d2h-code-side-line",CSSLineClass:l.CSSLineClass})}},e.prototype.generateFileHtml=function(e){var t=this,n=s.newMatcherFn(s.newDistanceFn((function(t){return l.deconstructLine(t.content,e.isCombined).content})));return e.blocks.map((function(i){var r={left:t.makeHeaderHtml(i.header,e),right:t.makeHeaderHtml("")};return t.applyLineGroupping(i).forEach((function(i){var a=i[0],o=i[1],s=i[2];if(o.length&&s.length&&!a.length)t.applyRematchMatching(o,s,n).map((function(n){var i=n[0],a=n[1],o=t.processChangedLines(e.isCombined,i,a),s=o.left,l=o.right;r.left+=s,r.right+=l}));else if(a.length)a.forEach((function(n){var i=l.deconstructLine(n.content,e.isCombined),a=i.prefix,o=i.content,s=t.generateLineHtml({type:l.CSSLineClass.CONTEXT,prefix:a,content:o,number:n.oldNumber},{type:l.CSSLineClass.CONTEXT,prefix:a,content:o,number:n.newNumber}),f=s.left,u=s.right;r.left+=f,r.right+=u}));else if(o.length||s.length){var f=t.processChangedLines(e.isCombined,o,s),u=f.left,d=f.right;r.left+=u,r.right+=d}else console.error("Unknown state reached while processing groups of lines",a,o,s)})),r})).reduce((function(e,t){return{left:e.left+t.left,right:e.right+t.right}}),{left:"",right:""})},e.prototype.applyLineGroupping=function(e){for(var t=[],n=[],i=[],r=0;r<e.lines.length;r++){var a=e.lines[r];(a.type!==f.LineType.INSERT&&i.length||a.type===f.LineType.CONTEXT&&n.length>0)&&(t.push([[],n,i]),n=[],i=[]),a.type===f.LineType.CONTEXT?t.push([[a],[],[]]):a.type===f.LineType.INSERT&&0===n.length?t.push([[],[],[a]]):a.type===f.LineType.INSERT&&n.length>0?i.push(a):a.type===f.LineType.DELETE&&n.push(a)}return(n.length||i.length)&&(t.push([[],n,i]),n=[],i=[]),t},e.prototype.applyRematchMatching=function(e,t,n){var i=e.length*t.length,r=Math.max.apply(null,[0].concat(e.concat(t).map((function(e){return e.content.length}))));return i<this.config.matchingMaxComparisons&&r<this.config.maxLineSizeInBlockForComparison&&("lines"===this.config.matching||"words"===this.config.matching)?n(e,t):[[e,t]]},e.prototype.makeHeaderHtml=function(e,t){return this.hoganUtils.render(u,"block-header",{CSSLineClass:l.CSSLineClass,blockHeader:(null==t?void 0:t.isTooBig)?e:l.escapeForHtml(e),lineClass:"d2h-code-side-linenumber",contentClass:"d2h-code-side-line"})},e.prototype.processChangedLines=function(e,t,n){for(var r={right:"",left:""},a=Math.max(t.length,n.length),o=0;o<a;o++){var s=t[o],f=n[o],u=void 0!==s&&void 0!==f?l.diffHighlight(s.content,f.content,e,this.config):void 0,d=void 0!==s&&void 0!==s.oldNumber?i(i({},void 0!==u?{prefix:u.oldLine.prefix,content:u.oldLine.content,type:l.CSSLineClass.DELETE_CHANGES}:i(i({},l.deconstructLine(s.content,e)),{type:l.toCSSClass(s.type)})),{number:s.oldNumber}):void 0,c=void 0!==f&&void 0!==f.newNumber?i(i({},void 0!==u?{prefix:u.newLine.prefix,content:u.newLine.content,type:l.CSSLineClass.INSERT_CHANGES}:i(i({},l.deconstructLine(f.content,e)),{type:l.toCSSClass(f.type)})),{number:f.newNumber}):void 0,h=this.generateLineHtml(d,c),p=h.left,b=h.right;r.left+=p,r.right+=b}return r},e.prototype.generateLineHtml=function(e,t){return{left:this.generateSingleHtml(e),right:this.generateSingleHtml(t)}},e.prototype.generateSingleHtml=function(e){var t="d2h-code-side-linenumber",n="d2h-code-side-line";return this.hoganUtils.render(u,"line",{type:(null==e?void 0:e.type)||l.CSSLineClass.CONTEXT+" d2h-emptyplaceholder",lineClass:void 0!==e?t:t+" d2h-code-side-emptyplaceholder",contentClass:void 0!==e?n:n+" d2h-code-side-emptyplaceholder",prefix:" "===(null==e?void 0:e.prefix)?"&nbsp;":null==e?void 0:e.prefix,content:null==e?void 0:e.content,lineNumber:null==e?void 0:e.number})},e}();t.default=d},699:(e,t)=>{"use strict";var n;Object.defineProperty(t,"__esModule",{value:!0}),t.DiffStyleType=t.LineMatchingType=t.OutputFormatType=t.LineType=void 0,(n=t.LineType||(t.LineType={})).INSERT="insert",n.DELETE="delete",n.CONTEXT="context",t.OutputFormatType={LINE_BY_LINE:"line-by-line",SIDE_BY_SIDE:"side-by-side"},t.LineMatchingType={LINES:"lines",WORDS:"words",NONE:"none"},t.DiffStyleType={WORD:"word",CHAR:"char"}},593:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.hashCode=t.unifyPath=t.escapeForRegExp=void 0;var n=RegExp("["+["-","[","]","/","{","}","(",")","*","+","?",".","\\","^","$","|"].join("\\")+"]","g");t.escapeForRegExp=function(e){return e.replace(n,"\\$&")},t.unifyPath=function(e){return e?e.replace(/\\/g,"/"):e},t.hashCode=function(e){var t,n,i=0;for(t=0,n=e.length;t<n;t++)i=(i<<5)-i+e.charCodeAt(t),i|=0;return i}}},t={},function n(i){var r=t[i];if(void 0!==r)return r.exports;var a=t[i]={exports:{}};return e[i].call(a.exports,a,a.exports,n),a.exports}(834);var e,t}));
\ No newline at end of file
diff --git a/nautobot_golden_config/tables.py b/nautobot_golden_config/tables.py
index 4df94bdc..e01ee415 100644
--- a/nautobot_golden_config/tables.py
+++ b/nautobot_golden_config/tables.py
@@ -194,6 +194,29 @@ class Meta(BaseTable.Meta):
         fields = ("device", "feature", "compliance")
 
 
+class DeleteGoldenConfigTable(BaseTable):
+    """
+    Table used in bulk delete confirmation.
+
+    This is required since there model is different when deleting the record compared to when viewing the records initially via Device.
+    """
+
+    pk = ToggleColumn()
+
+    def __init__(self, *args, **kwargs):
+        """Remove all fields from showing except device ."""
+        super().__init__(*args, **kwargs)
+        for feature in list(self.base_columns.keys()):  # pylint: disable=no-member
+            if feature not in ["pk", "device"]:
+                self.base_columns.pop(feature)  # pylint: disable=no-member
+                self.sequence.remove(feature)
+
+    class Meta(BaseTable.Meta):
+        """Meta for class DeleteGoldenConfigTable."""
+
+        model = models.GoldenConfig
+
+
 # GoldenConfig
 
 
@@ -215,11 +238,17 @@ def __init__(self, *args, **kwargs):
     )
 
     if ENABLE_BACKUP:
-        backup_last_success_date = Column(verbose_name="Backup Status", empty_values=())
+        backup_last_success_date = Column(
+            verbose_name="Backup Status", empty_values=(), order_by="goldenconfig__backup_last_success_date"
+        )
     if ENABLE_INTENDED:
-        intended_last_success_date = Column(verbose_name="Intended Status", empty_values=())
+        intended_last_success_date = Column(
+            verbose_name="Intended Status", empty_values=(), order_by="goldenconfig__intended_last_success_date"
+        )
     if ENABLE_COMPLIANCE:
-        compliance_last_success_date = Column(verbose_name="Compliance Status", empty_values=())
+        compliance_last_success_date = Column(
+            verbose_name="Compliance Status", empty_values=(), order_by="goldenconfig__compliance_last_success_date"
+        )
 
     actions = TemplateColumn(
         template_code=ALL_ACTIONS, verbose_name="Actions", extra_context=CONFIG_FEATURES, orderable=False
diff --git a/nautobot_golden_config/templates/nautobot_golden_config/compliance_overview_report.html b/nautobot_golden_config/templates/nautobot_golden_config/compliance_overview_report.html
index 4eb1b943..668dba5d 100644
--- a/nautobot_golden_config/templates/nautobot_golden_config/compliance_overview_report.html
+++ b/nautobot_golden_config/templates/nautobot_golden_config/compliance_overview_report.html
@@ -20,7 +20,7 @@ <h1>{% block title %}Overview Reports{% endblock %}</h1>
             {% if bar_chart is not None %}
                 {% block graphic  %}
                     <div id="content">
-                        <img src= "data:image/png;base64,{{ bar_chart|safe }}" >
+                        <img src="data:image/png;base64,{{ bar_chart|safe }}" style="width:100%">
                     </div>
                 {% endblock %}
             {% else %}
diff --git a/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails.html b/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails.html
index 4a94a5dd..7e9d415f 100644
--- a/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails.html
+++ b/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails.html
@@ -2,8 +2,7 @@
 {% load buttons %}
 
 {% block content %}
-<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />
-<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html.min.js"></script>
+{% include "nautobot_golden_config/dff2html_base.html" %}
 <style>
     .d2h-tag {
         display: none;
diff --git a/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails_modal.html b/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails_modal.html
index 928a0145..349d981c 100644
--- a/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails_modal.html
+++ b/nautobot_golden_config/templates/nautobot_golden_config/configcompliancedetails_modal.html
@@ -1,5 +1,4 @@
-<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />
-<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html.min.js"></script>
+{% include "nautobot_golden_config/dff2html_base.html" %}
 <style>
     .d2h-tag {
         display: none;
diff --git a/nautobot_golden_config/templates/nautobot_golden_config/dff2html_base.html b/nautobot_golden_config/templates/nautobot_golden_config/dff2html_base.html
new file mode 100644
index 00000000..6a2cde15
--- /dev/null
+++ b/nautobot_golden_config/templates/nautobot_golden_config/dff2html_base.html
@@ -0,0 +1,4 @@
+{% load static %}
+<!-- Reference https://cdn.jsdelivr.net/npm/diff2html/bundles/ and obtain files and version folder name -->
+<link rel="stylesheet" type="text/css" href="{% static 'nautobot_golden_config/diff2html-3.4.13/diff2html.min.css' %}"/>
+<script type="text/javascript" src="{% static 'nautobot_golden_config/diff2html-3.4.13/diff2html.min.js' %}"></script>
\ No newline at end of file
diff --git a/nautobot_golden_config/templates/nautobot_golden_config/goldenconfig_list.html b/nautobot_golden_config/templates/nautobot_golden_config/goldenconfig_list.html
index cf019adf..dcc77dd0 100644
--- a/nautobot_golden_config/templates/nautobot_golden_config/goldenconfig_list.html
+++ b/nautobot_golden_config/templates/nautobot_golden_config/goldenconfig_list.html
@@ -82,8 +82,6 @@ <h1 class="modal-title">Golden Configuration</h4>
 {% endblock %}
 {% block javascript %}
 <script src="{% static 'js/tableconfig.js' %}"></script>
-<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />
-<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html.min.js"></script>
 <script>
     $( document ).ready(function(){
         $('.openBtn').on('click',function(){
diff --git a/nautobot_golden_config/utilities/management.py b/nautobot_golden_config/utilities/management.py
index 572b50d1..6fdd90fb 100644
--- a/nautobot_golden_config/utilities/management.py
+++ b/nautobot_golden_config/utilities/management.py
@@ -30,7 +30,7 @@ def job_runner(handle_class, job_class, device=None, user=None):
     job_content_type = ContentType.objects.get(app_label="extras", model="job")
 
     # Run the job and create a new JobResult
-    handle_class.stdout.write("[{:%H:%M:%S}] Running {}...".format(timezone.now(), job_class.class_path))
+    handle_class.stdout.write(f"[{timezone.now():%H:%M:%S}] Running {job_class.class_path}...")
 
     job_result = JobResult.enqueue_job(
         run_job,
@@ -54,13 +54,7 @@ def job_runner(handle_class, job_class, device=None, user=None):
             continue
 
         handle_class.stdout.write(
-            "\t{}: {} success, {} info, {} warning, {} failure".format(
-                test_name,
-                attrs["success"],
-                attrs["info"],
-                attrs["warning"],
-                attrs["failure"],
-            )
+            f"\t{test_name}: {attrs['success']} success, {attrs['info']} info, {attrs['warning']} warning, {attrs['failure']} failure"
         )
 
         for log_entry in attrs["log"]:
@@ -88,10 +82,8 @@ def job_runner(handle_class, job_class, device=None, user=None):
         status = handle_class.style.ERROR("ERRORED")
     else:
         status = handle_class.style.SUCCESS("SUCCESS")
-    handle_class.stdout.write("[{:%H:%M:%S}] {}: {}".format(timezone.now(), job_class.class_path, status))
+    handle_class.stdout.write(f"[{timezone.now():%H:%M:%S}] {job_class.class_path}: {status}")
 
     # Wrap things up
-    handle_class.stdout.write(
-        "[{:%H:%M:%S}] {}: Duration {}".format(timezone.now(), job_class.class_path, job_result.duration)
-    )
-    handle_class.stdout.write("[{:%H:%M:%S}] Finished".format(timezone.now()))
+    handle_class.stdout.write(f"[{timezone.now():%H:%M:%S}] {job_class.class_path}: Duration {job_result.duration}")
+    handle_class.stdout.write(f"[{timezone.now():%H:%M:%S}] Finished")
diff --git a/nautobot_golden_config/views.py b/nautobot_golden_config/views.py
index 18cda8b0..01685413 100644
--- a/nautobot_golden_config/views.py
+++ b/nautobot_golden_config/views.py
@@ -1,35 +1,34 @@
 """Django views for Nautobot Golden Configuration."""
-from datetime import datetime, timezone
-
 import base64
+import difflib
 import io
 import json
 import logging
 import urllib
-import difflib
-import yaml
+from datetime import datetime, timezone
 
 import matplotlib.pyplot as plt
+import nautobot
 import numpy as np
-from packaging.version import Version
-
+import yaml
 from django.contrib import messages
-from django.db.models import F, Q, Max
-from django.db.models import Count, FloatField, ExpressionWrapper, ProtectedError
-from django.shortcuts import render, redirect
+from django.db.models import Count, ExpressionWrapper, F, FloatField, Max, ProtectedError, Q
+from django.forms import ModelMultipleChoiceField, MultipleHiddenInput
+from django.shortcuts import redirect, render
 from django_pivot.pivot import pivot
-
-import nautobot
-from nautobot.dcim.models import Device
 from nautobot.core.views import generic
-
-from nautobot.utilities.utils import csv_format
+from nautobot.dcim.filters import DeviceFilterSet
+from nautobot.dcim.forms import DeviceFilterForm
+from nautobot.dcim.models import Device
+from nautobot.extras.models import CustomField
 from nautobot.utilities.error_handlers import handle_protectederror
+from nautobot.utilities.forms import ConfirmationForm
+from nautobot.utilities.utils import csv_format
 from nautobot.utilities.views import ContentTypePermissionRequiredMixin
+from packaging.version import Version
 
 from nautobot_golden_config import filters, forms, models, tables
-
-from nautobot_golden_config.utilities.constant import PLUGIN_CFG, ENABLE_COMPLIANCE, CONFIG_FEATURES
+from nautobot_golden_config.utilities.constant import CONFIG_FEATURES, ENABLE_COMPLIANCE, PLUGIN_CFG
 from nautobot_golden_config.utilities.graphql import graph_ql_query
 
 LOGGER = logging.getLogger(__name__)
@@ -47,8 +46,8 @@ class GoldenConfigListView(generic.ObjectListView):
     """View for displaying the configuration management status for backup, intended, diff, and SoT Agg."""
 
     table = tables.GoldenConfigTable
-    filterset = filters.GoldenConfigFilterSet
-    filterset_form = forms.GoldenConfigFilterForm
+    filterset = DeviceFilterSet
+    filterset_form = DeviceFilterForm
     queryset = Device.objects.all()
     template_name = "nautobot_golden_config/goldenconfig_list.html"
 
@@ -60,13 +59,114 @@ def alter_queryset(self, request):
         """Build actual runtime queryset as the build time queryset provides no information."""
         return self.queryset.filter(id__in=models.GoldenConfigSetting.objects.first().get_queryset())
 
+    def queryset_to_csv(self):
+        """Override nautobot default to account for using Device model for GoldenConfig data."""
+        csv_data = []
+        custom_fields = []
+
+        # Start with the column headers
+        headers = models.GoldenConfig.csv_headers.copy()
+
+        # Add custom field headers, if any
+        if hasattr(models.GoldenConfig, "_custom_field_data"):
+            for custom_field in CustomField.objects.get_for_model(models.GoldenConfig):
+                headers.append(custom_field.name)
+                custom_fields.append(custom_field.name)
+
+        csv_data.append(",".join(headers))
+
+        # Iterate through the queryset appending each object
+        for obj in models.GoldenConfig.objects.all():
+            data = obj.to_csv()
+
+            for custom_field in custom_fields:
+                data += (obj.cf.get(custom_field, ""),)
+
+            csv_data.append(csv_format(data))
+
+        return "\n".join(csv_data)
+
 
 class GoldenConfigBulkDeleteView(generic.BulkDeleteView):
     """Standard view for bulk deletion of data."""
 
-    queryset = models.GoldenConfig.objects.all()
+    queryset = Device.objects.all()
     table = tables.GoldenConfigTable
-    filterset = filters.GoldenConfigFilterSet
+    filterset = DeviceFilterSet
+
+    def post(self, request, **kwargs):
+        """Delete instances based on post request data."""
+        # This is a deviation from standard Nautobot, since the objectlistview is shown on devices, but
+        # displays elements from GoldenConfig model. We have to override attempting to delete from the Device model.
+
+        model = self.queryset.model
+
+        pk_list = request.POST.getlist("pk")
+
+        form_cls = self.get_form()
+
+        if "_confirm" in request.POST:
+            form = form_cls(request.POST)
+            if form.is_valid():
+                LOGGER.debug("Form validation was successful")
+
+                # Delete objects
+                queryset = models.GoldenConfig.objects.filter(pk__in=pk_list)
+                try:
+                    deleted_count = queryset.delete()[1][models.GoldenConfig._meta.label]
+                except ProtectedError as error:
+                    LOGGER.info("Caught ProtectedError while attempting to delete objects")
+                    handle_protectederror(queryset, request, error)
+                    return redirect(self.get_return_url(request))
+
+                msg = f"Deleted {deleted_count} {models.GoldenConfig._meta.verbose_name_plural}"
+                LOGGER.info(msg)
+                messages.success(request, msg)
+                return redirect(self.get_return_url(request))
+
+            LOGGER.debug("Form validation failed")
+
+        else:
+            # From the list of Device IDs, get the GoldenConfig IDs
+            obj_to_del = [
+                item[0] for item in models.GoldenConfig.objects.filter(device__pk__in=pk_list).values_list("id")
+            ]
+
+            form = form_cls(
+                initial={
+                    "pk": obj_to_del,
+                    "return_url": self.get_return_url(request),
+                }
+            )
+        # Levarge a custom table just for deleting
+        table = tables.DeleteGoldenConfigTable(models.GoldenConfig.objects.filter(pk__in=obj_to_del), orderable=False)
+        if not table.rows:
+            messages.warning(
+                request,
+                f"No {model._meta.verbose_name_plural} were selected for deletion.",
+            )
+            return redirect(self.get_return_url(request))
+
+        context = {
+            "form": form,
+            "obj_type_plural": model._meta.verbose_name_plural,
+            "table": table,
+            "return_url": self.get_return_url(request),
+        }
+        return render(request, self.template_name, context)
+
+    def get_form(self):
+        """Override standard form."""
+
+        class BulkDeleteForm(ConfirmationForm):
+            """Local class override."""
+
+            pk = ModelMultipleChoiceField(queryset=models.GoldenConfig.objects.all(), widget=MultipleHiddenInput)
+
+        if self.form:
+            return self.form
+
+        return BulkDeleteForm
 
 
 #
@@ -100,22 +200,22 @@ def extra_context(self):
     def queryset_to_csv(self):
         """Export queryset of objects as comma-separated value (CSV)."""
 
-        def conver_to_str(val):
-            if val is False:  # pylint: disable=no-else-return
+        def convert_to_str(val):
+            if val is None:
+                return "N/A"
+            if bool(val) is False:
                 return "non-compliant"
-            elif val is True:
+            if bool(val) is True:
                 return "compliant"
-            return "N/A"
+            raise ValueError(f"Expecting one of 'N/A', 0, or 1, got {val}")
 
         csv_data = []
-        headers = sorted(list(models.ConfigCompliance.objects.values_list("feature", flat=True).distinct()))
+        headers = sorted(list(models.ComplianceFeature.objects.values_list("name", flat=True).distinct()))
         csv_data.append(",".join(list(["Device name"] + headers)))
-        for obj in self.alter_queryset(None).values():
+        for obj in self.alter_queryset(None):
             # From all of the unique fields, obtain the columns, using list comprehension, add values per column,
             # as some fields may not exist for every device.
-            row = [Device.objects.get(id=obj["device_id"]).name] + [
-                conver_to_str(obj.get(header)) for header in headers
-            ]
+            row = [obj.get("device__name")] + [convert_to_str(obj.get(header)) for header in headers]
             csv_data.append(csv_format(row))
         return "\n".join(csv_data)
 
@@ -171,7 +271,7 @@ def post(self, request, **kwargs):
                     handle_protectederror(queryset, request, error)
                     return redirect(self.get_return_url(request))
 
-                msg = "Deleted {} {}".format(deleted_count, model._meta.verbose_name_plural)
+                msg = f"Deleted {deleted_count} {model._meta.verbose_name_plural}"
                 LOGGER.info(msg)
                 messages.success(request, msg)
                 return redirect(self.get_return_url(request))
@@ -191,7 +291,7 @@ def post(self, request, **kwargs):
         if not table.rows:
             messages.warning(
                 request,
-                "No {} were selected for deletion.".format(model._meta.verbose_name_plural),
+                f"No {model._meta.verbose_name_plural} were selected for deletion.",
             )
             return redirect(self.get_return_url(request))
 
@@ -456,7 +556,7 @@ def autolabel(rects):
             for rect in rects:
                 height = rect.get_height()
                 axis.annotate(
-                    "{}".format(height),
+                    f"{height}",
                     xy=(rect.get_x() + rect.get_width() / 2, 0.5),
                     xytext=(0, 3),  # 3 points vertical offset
                     textcoords="offset points",
@@ -585,7 +685,7 @@ def queryset_to_csv(self):
         )
         csv_data.append(",".join([]))
 
-        qs = self.queryset.values("rule", "count", "compliant", "non_compliant", "comp_percent")
+        qs = self.queryset.values("rule__feature__name", "count", "compliant", "non_compliant", "comp_percent")
         csv_data.append(",".join(["Total" if item == "count" else item.capitalize() for item in qs[0].keys()]))
         for obj in qs:
             csv_data.append(
diff --git a/poetry.lock b/poetry.lock
index 68497dae..54e5e7de 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -28,14 +28,6 @@ category = "main"
 optional = false
 python-versions = "*"
 
-[[package]]
-name = "appdirs"
-version = "1.4.4"
-description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-category = "dev"
-optional = false
-python-versions = "*"
-
 [[package]]
 name = "asgiref"
 version = "3.4.1"
@@ -52,17 +44,17 @@ tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"]
 
 [[package]]
 name = "astroid"
-version = "2.6.6"
+version = "2.9.0"
 description = "An abstract syntax tree for Python with inference support."
-category = "main"
+category = "dev"
 optional = false
 python-versions = "~=3.6"
 
 [package.dependencies]
 lazy-object-proxy = ">=1.4.0"
-typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""}
-typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
-wrapt = ">=1.11,<1.13"
+typed-ast = {version = ">=1.4.0,<2.0", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""}
+typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""}
+wrapt = ">=1.11,<1.14"
 
 [[package]]
 name = "attrs"
@@ -80,7 +72,7 @@ tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>
 
 [[package]]
 name = "bandit"
-version = "1.7.0"
+version = "1.7.1"
 description = "Security oriented static analyser for python code."
 category = "dev"
 optional = false
@@ -90,7 +82,6 @@ python-versions = ">=3.5"
 colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
 GitPython = ">=1.0.1"
 PyYAML = ">=5.3.1"
-six = ">=1.10.0"
 stevedore = ">=1.20.0"
 
 [[package]]
@@ -119,26 +110,32 @@ python-versions = "*"
 
 [[package]]
 name = "black"
-version = "20.8b1"
+version = "21.11b1"
 description = "The uncompromising code formatter."
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.6.2"
 
 [package.dependencies]
-appdirs = "*"
 click = ">=7.1.2"
 dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""}
 mypy-extensions = ">=0.4.3"
-pathspec = ">=0.6,<1"
-regex = ">=2020.1.8"
-toml = ">=0.10.1"
-typed-ast = ">=1.4.0"
-typing-extensions = ">=3.7.4"
+pathspec = ">=0.9.0,<1"
+platformdirs = ">=2"
+regex = ">=2021.4.4"
+tomli = ">=0.2.6,<2.0.0"
+typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""}
+typing-extensions = [
+    {version = ">=3.10.0.0", markers = "python_version < \"3.10\""},
+    {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""},
+]
 
 [package.extras]
 colorama = ["colorama (>=0.4.3)"]
-d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
+d = ["aiohttp (>=3.7.4)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
+python2 = ["typed-ast (>=1.4.3)"]
+uvloop = ["uvloop (>=0.15.2)"]
 
 [[package]]
 name = "cached-property"
@@ -201,7 +198,7 @@ zstd = ["zstandard"]
 
 [[package]]
 name = "certifi"
-version = "2021.5.30"
+version = "2021.10.8"
 description = "Python package for providing Mozilla's CA Bundle."
 category = "main"
 optional = false
@@ -209,7 +206,7 @@ python-versions = "*"
 
 [[package]]
 name = "cffi"
-version = "1.14.6"
+version = "1.15.0"
 description = "Foreign Function Interface for Python calling C code."
 category = "main"
 optional = false
@@ -220,7 +217,7 @@ pycparser = "*"
 
 [[package]]
 name = "charset-normalizer"
-version = "2.0.6"
+version = "2.0.8"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 category = "main"
 optional = false
@@ -231,17 +228,18 @@ unicode_backport = ["unicodedata2"]
 
 [[package]]
 name = "ciscoconfparse"
-version = "1.5.46"
-description = ""
+version = "1.6.7"
+description = "Parse, Audit, Query, Build, and Modify Cisco IOS-style and JunOS-style configurations"
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = ">=3.6"
 
 [package.dependencies]
-colorama = "*"
-dnspython = "*"
-loguru = "*"
-passlib = "*"
+dnspython = ">=2.1.0,<3.0.0"
+ipaddr = "*"
+loguru = "0.5.3"
+passlib = ">=1.7.4,<2.0.0"
+toml = "0.10.2"
 
 [[package]]
 name = "click"
@@ -335,7 +333,7 @@ jinja2 = "*"
 
 [[package]]
 name = "cryptography"
-version = "3.4.8"
+version = "36.0.0"
 description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
 category = "main"
 optional = false
@@ -346,22 +344,19 @@ cffi = ">=1.12"
 
 [package.extras]
 docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
-docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
+docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
 pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
-sdist = ["setuptools-rust (>=0.11.4)"]
+sdist = ["setuptools_rust (>=0.11.4)"]
 ssh = ["bcrypt (>=3.1.5)"]
-test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
+test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
 
 [[package]]
 name = "cycler"
-version = "0.10.0"
+version = "0.11.0"
 description = "Composable style cycles"
 category = "main"
 optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = "*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "dataclasses"
@@ -373,7 +368,7 @@ python-versions = ">=3.6, <3.7"
 
 [[package]]
 name = "deepdiff"
-version = "5.5.0"
+version = "5.6.0"
 description = "Deep Difference and Search of any Python object/data."
 category = "main"
 optional = false
@@ -393,6 +388,20 @@ category = "main"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
+[[package]]
+name = "deprecated"
+version = "1.2.13"
+description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[package.dependencies]
+wrapt = ">=1.10,<2"
+
+[package.extras]
+dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"]
+
 [[package]]
 name = "django"
 version = "3.1.13"
@@ -412,11 +421,11 @@ bcrypt = ["bcrypt"]
 
 [[package]]
 name = "django-appconf"
-version = "1.0.4"
+version = "1.0.5"
 description = "A helper class for handling configuration defaults of packaged apps gracefully."
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = ">=3.6"
 
 [package.dependencies]
 django = "*"
@@ -473,7 +482,7 @@ Django = "*"
 name = "django-debug-toolbar"
 version = "3.2.2"
 description = "A configurable set of panels that display various debug information about the current request/response."
-category = "main"
+category = "dev"
 optional = false
 python-versions = ">=3.6"
 
@@ -695,17 +704,17 @@ validation = ["swagger-spec-validator (>=2.1.0)"]
 
 [[package]]
 name = "flake8"
-version = "3.9.2"
+version = "4.0.1"
 description = "the modular source code checker: pep8 pyflakes and co"
 category = "dev"
 optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+python-versions = ">=3.6"
 
 [package.dependencies]
-importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
+importlib-metadata = {version = "<4.3", markers = "python_version < \"3.8\""}
 mccabe = ">=0.6.0,<0.7.0"
-pycodestyle = ">=2.7.0,<2.8.0"
-pyflakes = ">=2.3.0,<2.4.0"
+pycodestyle = ">=2.8.0,<2.9.0"
+pyflakes = ">=2.4.0,<2.5.0"
 
 [[package]]
 name = "funcy"
@@ -725,14 +734,14 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 
 [[package]]
 name = "gitdb"
-version = "4.0.7"
+version = "4.0.9"
 description = "Git Object Database"
 category = "main"
 optional = false
-python-versions = ">=3.4"
+python-versions = ">=3.6"
 
 [package.dependencies]
-smmap = ">=3.0.1,<5"
+smmap = ">=3.0.1,<6"
 
 [[package]]
 name = "gitpython"
@@ -819,7 +828,7 @@ six = ">=1.12"
 
 [[package]]
 name = "idna"
-version = "3.2"
+version = "3.3"
 description = "Internationalized Domain Names in Applications (IDNA)"
 category = "main"
 optional = false
@@ -857,7 +866,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake
 
 [[package]]
 name = "importlib-resources"
-version = "5.2.2"
+version = "5.4.0"
 description = "Read resources from Python packages"
 category = "main"
 optional = false
@@ -868,7 +877,7 @@ zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
 
 [package.extras]
 docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
-testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"]
+testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"]
 
 [[package]]
 name = "inflection"
@@ -886,6 +895,14 @@ category = "dev"
 optional = false
 python-versions = "*"
 
+[[package]]
+name = "ipaddr"
+version = "2.2.0"
+description = "Google's IP address manipulation library"
+category = "main"
+optional = false
+python-versions = "*"
+
 [[package]]
 name = "isort"
 version = "5.8.0"
@@ -941,16 +958,16 @@ format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator
 
 [[package]]
 name = "junos-eznc"
-version = "2.5.4"
+version = "2.6.3"
 description = "Junos 'EZ' automation for non-programmers"
 category = "main"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [package.dependencies]
 jinja2 = ">=2.7.1"
 lxml = ">=3.2.4"
-ncclient = ">=0.6.3"
+ncclient = "0.6.9"
 netaddr = "*"
 paramiko = ">=1.15.2"
 pyparsing = "*"
@@ -1003,7 +1020,7 @@ zookeeper = ["kazoo (>=1.3.1)"]
 name = "lazy-object-proxy"
 version = "1.6.0"
 description = "A fast and thorough lazy object proxy."
-category = "main"
+category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 
@@ -1025,7 +1042,7 @@ dev = ["codecov (>=2.0.15)", "colorama (>=0.3.4)", "flake8 (>=3.7.7)", "tox (>=3
 
 [[package]]
 name = "lxml"
-version = "4.6.3"
+version = "4.6.4"
 description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
 category = "main"
 optional = false
@@ -1118,7 +1135,7 @@ textfsm = "*"
 
 [[package]]
 name = "nautobot"
-version = "1.1.3"
+version = "1.1.4"
 description = "Source of truth and network automation platform."
 category = "main"
 optional = false
@@ -1164,7 +1181,7 @@ mysql = ["mysqlclient (>=2.0.3,<2.1.0)"]
 
 [[package]]
 name = "nautobot-plugin-nornir"
-version = "0.9.4"
+version = "0.9.7"
 description = "Nautobot Nornir plugin."
 category = "main"
 optional = false
@@ -1172,11 +1189,12 @@ python-versions = ">=3.6,<4.0"
 
 [package.dependencies]
 nautobot = ">=1.0.0"
-nornir-nautobot = ">=2.0.0,<3.0.0"
+netutils = ">=0.2.5"
+nornir-nautobot = ">=2.2.0,<3.0.0"
 
 [[package]]
 name = "ncclient"
-version = "0.6.12"
+version = "0.6.9"
 description = "Python library for NETCONF clients"
 category = "main"
 optional = false
@@ -1219,7 +1237,7 @@ test = ["pyyaml (>=5.1.2)", "pytest (>=5.1.2)"]
 
 [[package]]
 name = "netutils"
-version = "0.2.2"
+version = "0.2.5"
 description = "Common helper functions useful in network automation."
 category = "main"
 optional = false
@@ -1268,7 +1286,7 @@ nornir = ">=3,<4"
 
 [[package]]
 name = "nornir-nautobot"
-version = "2.1.0"
+version = "2.2.0"
 description = "Nornir Nautobot"
 category = "main"
 optional = false
@@ -1309,7 +1327,7 @@ nornir = ">=3,<4"
 
 [[package]]
 name = "ntc-templates"
-version = "2.3.2"
+version = "3.0.0"
 description = "TextFSM Templates for Network Devices, and Python wrapper for TextFSM's CliTable."
 category = "main"
 optional = false
@@ -1349,18 +1367,18 @@ python-versions = ">=3.5"
 
 [[package]]
 name = "packaging"
-version = "21.0"
+version = "21.3"
 description = "Core utilities for Python packages"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 
 [package.dependencies]
-pyparsing = ">=2.0.2"
+pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
 
 [[package]]
 name = "paramiko"
-version = "2.7.2"
+version = "2.8.0"
 description = "SSH2 protocol library"
 category = "main"
 optional = false
@@ -1401,7 +1419,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
 
 [[package]]
 name = "pbr"
-version = "5.6.0"
+version = "5.8.0"
 description = "Python Build Reasonableness"
 category = "dev"
 optional = false
@@ -1415,9 +1433,21 @@ category = "main"
 optional = false
 python-versions = ">=3.6"
 
+[[package]]
+name = "platformdirs"
+version = "2.4.0"
+description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+
+[package.extras]
+docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
+test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
+
 [[package]]
 name = "prometheus-client"
-version = "0.11.0"
+version = "0.12.0"
 description = "Python client for the Prometheus monitoring system."
 category = "main"
 optional = false
@@ -1461,15 +1491,15 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
 
 [[package]]
 name = "pycodestyle"
-version = "2.7.0"
+version = "2.8.0"
 description = "Python style guide checker"
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "pycparser"
-version = "2.20"
+version = "2.21"
 description = "C parser in Python"
 category = "main"
 optional = false
@@ -1477,7 +1507,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "pycryptodome"
-version = "3.10.1"
+version = "3.10.4"
 description = "Cryptographic library for Python"
 category = "main"
 optional = false
@@ -1485,15 +1515,18 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "pydocstyle"
-version = "5.1.1"
+version = "6.1.1"
 description = "Python docstring style checker"
 category = "dev"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 
 [package.dependencies]
 snowballstemmer = "*"
 
+[package.extras]
+toml = ["toml"]
+
 [[package]]
 name = "pyeapi"
 version = "0.8.4"
@@ -1511,7 +1544,7 @@ test = ["coverage", "mock"]
 
 [[package]]
 name = "pyflakes"
-version = "2.3.1"
+version = "2.4.0"
 description = "passive checker of Python programs"
 category = "dev"
 optional = false
@@ -1519,35 +1552,34 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "pyjwt"
-version = "2.1.0"
+version = "2.3.0"
 description = "JSON Web Token implementation in Python"
 category = "main"
 optional = false
 python-versions = ">=3.6"
 
 [package.extras]
-crypto = ["cryptography (>=3.3.1,<4.0.0)"]
-dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1,<4.0.0)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"]
+crypto = ["cryptography (>=3.3.1)"]
+dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"]
 docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
 tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
 
 [[package]]
 name = "pylint"
-version = "2.7.4"
+version = "2.12.0"
 description = "python code static checker"
 category = "dev"
 optional = false
 python-versions = "~=3.6"
 
 [package.dependencies]
-astroid = ">=2.5.2,<2.7"
+astroid = ">=2.9.0,<2.10"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 isort = ">=4.2.5,<6"
 mccabe = ">=0.6,<0.7"
-toml = ">=0.7.1"
-
-[package.extras]
-docs = ["sphinx (==3.5.1)", "python-docs-theme (==2020.12)"]
+platformdirs = ">=2.2.0"
+toml = ">=0.9.2"
+typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
 
 [[package]]
 name = "pylint-django"
@@ -1608,11 +1640,14 @@ docs = ["Sphinx (>=3.5.1,<4.0.0)"]
 
 [[package]]
 name = "pyparsing"
-version = "2.4.7"
+version = "3.0.6"
 description = "Python parsing module"
 category = "main"
 optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+python-versions = ">=3.6"
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
 
 [[package]]
 name = "pyrsistent"
@@ -1661,7 +1696,7 @@ postgresql = ["psycopg2"]
 
 [[package]]
 name = "pytz"
-version = "2021.1"
+version = "2021.3"
 description = "World timezone definitions, modern and historical"
 category = "main"
 optional = false
@@ -1669,7 +1704,7 @@ python-versions = "*"
 
 [[package]]
 name = "pyuwsgi"
-version = "2.0.19.1.post0"
+version = "2.0.20"
 description = "The uWSGI server"
 category = "main"
 optional = false
@@ -1685,18 +1720,21 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 
 [[package]]
 name = "redis"
-version = "3.5.3"
-description = "Python client for Redis key-value store"
+version = "4.0.2"
+description = "Python client for Redis database and key-value store"
 category = "main"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
+
+[package.dependencies]
+deprecated = "*"
 
 [package.extras]
-hiredis = ["hiredis (>=0.1.3)"]
+hiredis = ["hiredis (>=1.0.0)"]
 
 [[package]]
 name = "regex"
-version = "2021.8.28"
+version = "2021.11.10"
 description = "Alternative regular expression module, to replace re."
 category = "dev"
 optional = false
@@ -1814,15 +1852,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
 
 [[package]]
 name = "smmap"
-version = "4.0.0"
+version = "5.0.0"
 description = "A pure Python implementation of a sliding window memory map manager"
 category = "main"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 
 [[package]]
 name = "snowballstemmer"
-version = "2.1.0"
+version = "2.2.0"
 description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
 category = "dev"
 optional = false
@@ -1874,7 +1912,7 @@ python-versions = ">=3.5"
 
 [[package]]
 name = "stevedore"
-version = "3.4.0"
+version = "3.5.0"
 description = "Manage dynamic plugins for Python applications"
 category = "dev"
 optional = false
@@ -1894,7 +1932,7 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "swagger-spec-validator"
-version = "2.7.3"
+version = "2.7.4"
 description = "Validation of Swagger specifications"
 category = "main"
 optional = false
@@ -1940,13 +1978,21 @@ six = "*"
 name = "toml"
 version = "0.10.2"
 description = "Python Library for Tom's Obvious, Minimal Language"
-category = "dev"
+category = "main"
 optional = false
 python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 
+[[package]]
+name = "tomli"
+version = "1.2.2"
+description = "A lil' TOML parser"
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+
 [[package]]
 name = "transitions"
-version = "0.8.9"
+version = "0.8.10"
 description = "A lightweight, object-oriented Python state machine implementation with many extensions."
 category = "main"
 optional = false
@@ -1961,11 +2007,11 @@ test = ["pytest"]
 
 [[package]]
 name = "typed-ast"
-version = "1.4.3"
+version = "1.5.0"
 description = "a fork of Python 2 and 3 ast modules with type comment support"
-category = "main"
+category = "dev"
 optional = false
-python-versions = "*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "typing-extensions"
@@ -1977,15 +2023,15 @@ python-versions = "*"
 
 [[package]]
 name = "uritemplate"
-version = "3.0.1"
-description = "URI templates"
+version = "4.1.1"
+description = "Implementation of RFC 6570 URI Templates"
 category = "main"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "urllib3"
-version = "1.26.6"
+version = "1.26.7"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 category = "main"
 optional = false
@@ -2025,11 +2071,11 @@ dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
 
 [[package]]
 name = "wrapt"
-version = "1.12.1"
+version = "1.13.3"
 description = "Module for decorators, wrappers and monkey patching."
 category = "main"
 optional = false
-python-versions = "*"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
 
 [[package]]
 name = "yamllint"
@@ -2056,7 +2102,7 @@ pyyaml = "*"
 
 [[package]]
 name = "zipp"
-version = "3.5.0"
+version = "3.6.0"
 description = "Backport of pathlib-compatible object wrapper for zip files"
 category = "main"
 optional = false
@@ -2069,7 +2115,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.6"
-content-hash = "3030f4c4b6b3552026b38ac3cfaa31c771ffe1c2f8b2898eaeff9d36bea38915"
+content-hash = "a6a5edda2ec37927958c11ef415aae09057bd447250bb5d9644d144bef54f874"
 
 [metadata.files]
 aiocontextvars = [
@@ -2084,25 +2130,21 @@ aniso8601 = [
     {file = "aniso8601-7.0.0-py2.py3-none-any.whl", hash = "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b"},
     {file = "aniso8601-7.0.0.tar.gz", hash = "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e"},
 ]
-appdirs = [
-    {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
-    {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
-]
 asgiref = [
     {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"},
     {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"},
 ]
 astroid = [
-    {file = "astroid-2.6.6-py3-none-any.whl", hash = "sha256:ab7f36e8a78b8e54a62028ba6beef7561db4cdb6f2a5009ecc44a6f42b5697ef"},
-    {file = "astroid-2.6.6.tar.gz", hash = "sha256:3975a0bd5373bdce166e60c851cfcbaf21ee96de80ec518c1f4cb3e94c3fb334"},
+    {file = "astroid-2.9.0-py3-none-any.whl", hash = "sha256:776ca0b748b4ad69c00bfe0fff38fa2d21c338e12c84aa9715ee0d473c422778"},
+    {file = "astroid-2.9.0.tar.gz", hash = "sha256:5939cf55de24b92bda00345d4d0659d01b3c7dafb5055165c330bc7c568ba273"},
 ]
 attrs = [
     {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
     {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
 ]
 bandit = [
-    {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"},
-    {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"},
+    {file = "bandit-1.7.1-py3-none-any.whl", hash = "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4"},
+    {file = "bandit-1.7.1.tar.gz", hash = "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c"},
 ]
 bcrypt = [
     {file = "bcrypt-3.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6"},
@@ -2118,7 +2160,8 @@ billiard = [
     {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"},
 ]
 black = [
-    {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
+    {file = "black-21.11b1-py3-none-any.whl", hash = "sha256:802c6c30b637b28645b7fde282ed2569c0cd777dbe493a41b6a03c1d903f99ac"},
+    {file = "black-21.11b1.tar.gz", hash = "sha256:a042adbb18b3262faad5aff4e834ff186bb893f95ba3a8013f09de1e5569def2"},
 ]
 cached-property = [
     {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"},
@@ -2129,63 +2172,68 @@ celery = [
     {file = "celery-5.1.2.tar.gz", hash = "sha256:8d9a3de9162965e97f8e8cc584c67aad83b3f7a267584fa47701ed11c3e0d4b0"},
 ]
 certifi = [
-    {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"},
-    {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"},
+    {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
+    {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
 ]
 cffi = [
-    {file = "cffi-1.14.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c"},
-    {file = "cffi-1.14.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f0c5d1acbfca6ebdd6b1e3eded8d261affb6ddcf2186205518f1428b8569bb99"},
-    {file = "cffi-1.14.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99f27fefe34c37ba9875f224a8f36e31d744d8083e00f520f133cab79ad5e819"},
-    {file = "cffi-1.14.6-cp27-cp27m-win32.whl", hash = "sha256:55af55e32ae468e9946f741a5d51f9896da6b9bf0bbdd326843fec05c730eb20"},
-    {file = "cffi-1.14.6-cp27-cp27m-win_amd64.whl", hash = "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224"},
-    {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7"},
-    {file = "cffi-1.14.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33"},
-    {file = "cffi-1.14.6-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534"},
-    {file = "cffi-1.14.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a"},
-    {file = "cffi-1.14.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5"},
-    {file = "cffi-1.14.6-cp35-cp35m-win32.whl", hash = "sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca"},
-    {file = "cffi-1.14.6-cp35-cp35m-win_amd64.whl", hash = "sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218"},
-    {file = "cffi-1.14.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f"},
-    {file = "cffi-1.14.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872"},
-    {file = "cffi-1.14.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195"},
-    {file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9dc245e3ac69c92ee4c167fbdd7428ec1956d4e754223124991ef29eb57a09d"},
-    {file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8661b2ce9694ca01c529bfa204dbb144b275a31685a075ce123f12331be790b"},
-    {file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b315d709717a99f4b27b59b021e6207c64620790ca3e0bde636a6c7f14618abb"},
-    {file = "cffi-1.14.6-cp36-cp36m-win32.whl", hash = "sha256:80b06212075346b5546b0417b9f2bf467fea3bfe7352f781ffc05a8ab24ba14a"},
-    {file = "cffi-1.14.6-cp36-cp36m-win_amd64.whl", hash = "sha256:a9da7010cec5a12193d1af9872a00888f396aba3dc79186604a09ea3ee7c029e"},
-    {file = "cffi-1.14.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4373612d59c404baeb7cbd788a18b2b2a8331abcc84c3ba40051fcd18b17a4d5"},
-    {file = "cffi-1.14.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f10afb1004f102c7868ebfe91c28f4a712227fe4cb24974350ace1f90e1febbf"},
-    {file = "cffi-1.14.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fd4305f86f53dfd8cd3522269ed7fc34856a8ee3709a5e28b2836b2db9d4cd69"},
-    {file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d6169cb3c6c2ad50db5b868db6491a790300ade1ed5d1da29289d73bbe40b56"},
-    {file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d4b68e216fc65e9fe4f524c177b54964af043dde734807586cf5435af84045c"},
-    {file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33791e8a2dc2953f28b8d8d300dde42dd929ac28f974c4b4c6272cb2955cb762"},
-    {file = "cffi-1.14.6-cp37-cp37m-win32.whl", hash = "sha256:0c0591bee64e438883b0c92a7bed78f6290d40bf02e54c5bf0978eaf36061771"},
-    {file = "cffi-1.14.6-cp37-cp37m-win_amd64.whl", hash = "sha256:8eb687582ed7cd8c4bdbff3df6c0da443eb89c3c72e6e5dcdd9c81729712791a"},
-    {file = "cffi-1.14.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba6f2b3f452e150945d58f4badd92310449876c4c954836cfb1803bdd7b422f0"},
-    {file = "cffi-1.14.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:64fda793737bc4037521d4899be780534b9aea552eb673b9833b01f945904c2e"},
-    {file = "cffi-1.14.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9f3e33c28cd39d1b655ed1ba7247133b6f7fc16fa16887b120c0c670e35ce346"},
-    {file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26bb2549b72708c833f5abe62b756176022a7b9a7f689b571e74c8478ead51dc"},
-    {file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb687a11f0a7a1839719edd80f41e459cc5366857ecbed383ff376c4e3cc6afd"},
-    {file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2ad4d668a5c0645d281dcd17aff2be3212bc109b33814bbb15c4939f44181cc"},
-    {file = "cffi-1.14.6-cp38-cp38-win32.whl", hash = "sha256:487d63e1454627c8e47dd230025780e91869cfba4c753a74fda196a1f6ad6548"},
-    {file = "cffi-1.14.6-cp38-cp38-win_amd64.whl", hash = "sha256:c33d18eb6e6bc36f09d793c0dc58b0211fccc6ae5149b808da4a62660678b156"},
-    {file = "cffi-1.14.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:06c54a68935738d206570b20da5ef2b6b6d92b38ef3ec45c5422c0ebaf338d4d"},
-    {file = "cffi-1.14.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:f174135f5609428cc6e1b9090f9268f5c8935fddb1b25ccb8255a2d50de6789e"},
-    {file = "cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f3ebe6e73c319340830a9b2825d32eb6d8475c1dac020b4f0aa774ee3b898d1c"},
-    {file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c8d896becff2fa653dc4438b54a5a25a971d1f4110b32bd3068db3722c80202"},
-    {file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4922cd707b25e623b902c86188aca466d3620892db76c0bdd7b99a3d5e61d35f"},
-    {file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9e005e9bd57bc987764c32a1bee4364c44fdc11a3cc20a40b93b444984f2b87"},
-    {file = "cffi-1.14.6-cp39-cp39-win32.whl", hash = "sha256:eb9e2a346c5238a30a746893f23a9535e700f8192a68c07c0258e7ece6ff3728"},
-    {file = "cffi-1.14.6-cp39-cp39-win_amd64.whl", hash = "sha256:818014c754cd3dba7229c0f5884396264d51ffb87ec86e927ef0be140bfdb0d2"},
-    {file = "cffi-1.14.6.tar.gz", hash = "sha256:c9a875ce9d7fe32887784274dd533c57909b7b1dcadcc128a2ac21331a9765dd"},
+    {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"},
+    {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"},
+    {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"},
+    {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"},
+    {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"},
+    {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"},
+    {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"},
+    {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"},
+    {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"},
+    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"},
+    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"},
+    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"},
+    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"},
+    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"},
+    {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"},
+    {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"},
+    {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"},
+    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"},
+    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"},
+    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"},
+    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"},
+    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"},
+    {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"},
+    {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"},
+    {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"},
+    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"},
+    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"},
+    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"},
+    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"},
+    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"},
+    {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"},
+    {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"},
+    {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"},
+    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"},
+    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"},
+    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"},
+    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"},
+    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"},
+    {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"},
+    {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"},
+    {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"},
+    {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"},
+    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"},
+    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"},
+    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"},
+    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"},
+    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"},
+    {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"},
+    {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"},
+    {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"},
 ]
 charset-normalizer = [
-    {file = "charset-normalizer-2.0.6.tar.gz", hash = "sha256:5ec46d183433dcbd0ab716f2d7f29d8dee50505b3fdb40c6b985c7c4f5a3591f"},
-    {file = "charset_normalizer-2.0.6-py3-none-any.whl", hash = "sha256:5d209c0a931f215cee683b6445e2d77677e7e75e159f78def0db09d68fafcaa6"},
+    {file = "charset-normalizer-2.0.8.tar.gz", hash = "sha256:735e240d9a8506778cd7a453d97e817e536bb1fc29f4f6961ce297b9c7a917b0"},
+    {file = "charset_normalizer-2.0.8-py3-none-any.whl", hash = "sha256:83fcdeb225499d6344c8f7f34684c2981270beacc32ede2e669e94f7fa544405"},
 ]
 ciscoconfparse = [
-    {file = "ciscoconfparse-1.5.46-py3-none-any.whl", hash = "sha256:3e04ebbd8afefa3b653a7e3fd56ab4d8a1485f21c5a742a0a865e562f2cd4de2"},
-    {file = "ciscoconfparse-1.5.46.tar.gz", hash = "sha256:3eb0327ee341927be06ec5bc3f53e30edd280dcd42513fd2a0c7b1de64f02f46"},
+    {file = "ciscoconfparse-1.6.7-py3-none-any.whl", hash = "sha256:8c7b23e859f694b5c9293a557e0759445e6b9668d6705d38e057d8d7e64926c5"},
+    {file = "ciscoconfparse-1.6.7.tar.gz", hash = "sha256:953c83c330aac81f17a7fbe783b728f1cfc95e77f34a3382baa6e2a3d17d45c6"},
 ]
 click = [
     {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
@@ -2218,47 +2266,55 @@ coreschema = [
     {file = "coreschema-0.0.4.tar.gz", hash = "sha256:9503506007d482ab0867ba14724b93c18a33b22b6d19fb419ef2d239dd4a1607"},
 ]
 cryptography = [
-    {file = "cryptography-3.4.8-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a00cf305f07b26c351d8d4e1af84ad7501eca8a342dedf24a7acb0e7b7406e14"},
-    {file = "cryptography-3.4.8-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:f44d141b8c4ea5eb4dbc9b3ad992d45580c1d22bf5e24363f2fbf50c2d7ae8a7"},
-    {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0a7dcbcd3f1913f664aca35d47c1331fce738d44ec34b7be8b9d332151b0b01e"},
-    {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34dae04a0dce5730d8eb7894eab617d8a70d0c97da76b905de9efb7128ad7085"},
-    {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eb7bb0df6f6f583dd8e054689def236255161ebbcf62b226454ab9ec663746b"},
-    {file = "cryptography-3.4.8-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:9965c46c674ba8cc572bc09a03f4c649292ee73e1b683adb1ce81e82e9a6a0fb"},
-    {file = "cryptography-3.4.8-cp36-abi3-win32.whl", hash = "sha256:21ca464b3a4b8d8e86ba0ee5045e103a1fcfac3b39319727bc0fc58c09c6aff7"},
-    {file = "cryptography-3.4.8-cp36-abi3-win_amd64.whl", hash = "sha256:3520667fda779eb788ea00080124875be18f2d8f0848ec00733c0ec3bb8219fc"},
-    {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d2a6e5ef66503da51d2110edf6c403dc6b494cc0082f85db12f54e9c5d4c3ec5"},
-    {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a305600e7a6b7b855cd798e00278161b681ad6e9b7eca94c721d5f588ab212af"},
-    {file = "cryptography-3.4.8-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:3fa3a7ccf96e826affdf1a0a9432be74dc73423125c8f96a909e3835a5ef194a"},
-    {file = "cryptography-3.4.8-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:d9ec0e67a14f9d1d48dd87a2531009a9b251c02ea42851c060b25c782516ff06"},
-    {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b0fbfae7ff7febdb74b574055c7466da334a5371f253732d7e2e7525d570498"},
-    {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94fff993ee9bc1b2440d3b7243d488c6a3d9724cc2b09cdb297f6a886d040ef7"},
-    {file = "cryptography-3.4.8-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:8695456444f277af73a4877db9fc979849cd3ee74c198d04fc0776ebc3db52b9"},
-    {file = "cryptography-3.4.8-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:cd65b60cfe004790c795cc35f272e41a3df4631e2fb6b35aa7ac6ef2859d554e"},
-    {file = "cryptography-3.4.8.tar.gz", hash = "sha256:94cc5ed4ceaefcbe5bf38c8fba6a21fc1d365bb8fb826ea1688e3370b2e24a1c"},
+    {file = "cryptography-36.0.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:9511416e85e449fe1de73f7f99b21b3aa04fba4c4d335d30c486ba3756e3a2a6"},
+    {file = "cryptography-36.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:97199a13b772e74cdcdb03760c32109c808aff7cd49c29e9cf4b7754bb725d1d"},
+    {file = "cryptography-36.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:494106e9cd945c2cadfce5374fa44c94cfadf01d4566a3b13bb487d2e6c7959e"},
+    {file = "cryptography-36.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6fbbbb8aab4053fa018984bb0e95a16faeb051dd8cca15add2a27e267ba02b58"},
+    {file = "cryptography-36.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:684993ff6f67000a56454b41bdc7e015429732d65a52d06385b6e9de6181c71e"},
+    {file = "cryptography-36.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c702855cd3174666ef0d2d13dcc879090aa9c6c38f5578896407a7028f75b9f"},
+    {file = "cryptography-36.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d91bc9f535599bed58f6d2e21a2724cb0c3895bf41c6403fe881391d29096f1d"},
+    {file = "cryptography-36.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b17d83b3d1610e571fedac21b2eb36b816654d6f7496004d6a0d32f99d1d8120"},
+    {file = "cryptography-36.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:8982c19bb90a4fa2aad3d635c6d71814e38b643649b4000a8419f8691f20ac44"},
+    {file = "cryptography-36.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:24469d9d33217ffd0ce4582dfcf2a76671af115663a95328f63c99ec7ece61a4"},
+    {file = "cryptography-36.0.0-cp36-abi3-win32.whl", hash = "sha256:f6a5a85beb33e57998dc605b9dbe7deaa806385fdf5c4810fb849fcd04640c81"},
+    {file = "cryptography-36.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:2deab5ec05d83ddcf9b0916319674d3dae88b0e7ee18f8962642d3cde0496568"},
+    {file = "cryptography-36.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2049f8b87f449fc6190350de443ee0c1dd631f2ce4fa99efad2984de81031681"},
+    {file = "cryptography-36.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a776bae1629c8d7198396fd93ec0265f8dd2341c553dc32b976168aaf0e6a636"},
+    {file = "cryptography-36.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:aa94d617a4cd4cdf4af9b5af65100c036bce22280ebb15d8b5262e8273ebc6ba"},
+    {file = "cryptography-36.0.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5c49c9e8fb26a567a2b3fa0343c89f5d325447956cc2fc7231c943b29a973712"},
+    {file = "cryptography-36.0.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ef216d13ac8d24d9cd851776662f75f8d29c9f2d05cdcc2d34a18d32463a9b0b"},
+    {file = "cryptography-36.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:231c4a69b11f6af79c1495a0e5a85909686ea8db946935224b7825cfb53827ed"},
+    {file = "cryptography-36.0.0-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f92556f94e476c1b616e6daec5f7ddded2c082efa7cee7f31c7aeda615906ed8"},
+    {file = "cryptography-36.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d73e3a96c38173e0aa5646c31bf8473bc3564837977dd480f5cbeacf1d7ef3a3"},
+    {file = "cryptography-36.0.0.tar.gz", hash = "sha256:52f769ecb4ef39865719aedc67b4b7eae167bafa48dbc2a26dd36fa56460507f"},
 ]
 cycler = [
-    {file = "cycler-0.10.0-py2.py3-none-any.whl", hash = "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d"},
-    {file = "cycler-0.10.0.tar.gz", hash = "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"},
+    {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
+    {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"},
 ]
 dataclasses = [
     {file = "dataclasses-0.7-py3-none-any.whl", hash = "sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836"},
     {file = "dataclasses-0.7.tar.gz", hash = "sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6"},
 ]
 deepdiff = [
-    {file = "deepdiff-5.5.0-py3-none-any.whl", hash = "sha256:e054fed9dfe0d83d622921cbb3a3d0b3a6dd76acd2b6955433a0a2d35147774a"},
-    {file = "deepdiff-5.5.0.tar.gz", hash = "sha256:dd79b81c2d84bfa33aa9d94d456b037b68daff6bb87b80dfaa1eca04da68b349"},
+    {file = "deepdiff-5.6.0-py3-none-any.whl", hash = "sha256:ef3410ca31e059a9d10edfdff552245829835b3ecd03212dc5b533d45a6c3f57"},
+    {file = "deepdiff-5.6.0.tar.gz", hash = "sha256:e3f1c3a375c7ea5ca69dba6f7920f9368658318ff1d8a496293c79481f48e649"},
 ]
 defusedxml = [
     {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
     {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
 ]
+deprecated = [
+    {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"},
+    {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"},
+]
 django = [
     {file = "Django-3.1.13-py3-none-any.whl", hash = "sha256:a6e0d1ff11095b7394c079ade7094c73b2dc3df4a7a373c9b58ed73b77a97feb"},
     {file = "Django-3.1.13.tar.gz", hash = "sha256:9f8be75646f62204320b195062b1d696ba28aa3d45ee72fb7c888ffaebc5bdb2"},
 ]
 django-appconf = [
-    {file = "django-appconf-1.0.4.tar.gz", hash = "sha256:be58deb54a43d77d2e1621fe59f787681376d3cd0b8bd8e4758ef6c3a6453380"},
-    {file = "django_appconf-1.0.4-py2.py3-none-any.whl", hash = "sha256:1b1d0e1069c843ebe8ae5aa48ec52403b1440402b320c3e3a206a0907e97bb06"},
+    {file = "django-appconf-1.0.5.tar.gz", hash = "sha256:be3db0be6c81fa84742000b89a81c016d70ae66a7ccb620cdef592b1f1a6aaa4"},
+    {file = "django_appconf-1.0.5-py3-none-any.whl", hash = "sha256:ae9f864ee1958c815a965ed63b3fba4874eec13de10236ba063a788f9a17389d"},
 ]
 django-cacheops = [
     {file = "django-cacheops-5.1.tar.gz", hash = "sha256:d5851cd7bf3087384a1fcecfa8dddb8f55030eedfd6fdf127225b75bca0f99dd"},
@@ -2344,8 +2400,8 @@ drf-yasg = [
     {file = "drf_yasg-1.20.0-py2.py3-none-any.whl", hash = "sha256:8b72e5b1875931a8d11af407be3a9a5ba8776541492947a0df5bafda6b7f8267"},
 ]
 flake8 = [
-    {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
-    {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
+    {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
+    {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
 ]
 funcy = [
     {file = "funcy-1.16-py2.py3-none-any.whl", hash = "sha256:1d3fc5d42cf7564a6b2be04042d0df7a50c77903cf760a34786d0c9ebd659b25"},
@@ -2355,8 +2411,8 @@ future = [
     {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
 ]
 gitdb = [
-    {file = "gitdb-4.0.7-py3-none-any.whl", hash = "sha256:6c4cc71933456991da20917998acbe6cf4fb41eeaab7d6d67fbc05ecd4c865b0"},
-    {file = "gitdb-4.0.7.tar.gz", hash = "sha256:96bf5c08b157a666fec41129e6d327235284cca4c81e92109260f353ba138005"},
+    {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
+    {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"},
 ]
 gitpython = [
     {file = "GitPython-3.1.20-py3-none-any.whl", hash = "sha256:b1e1c269deab1b08ce65403cf14e10d2ef1f6c89e33ea7c5e5bb0222ea593b8a"},
@@ -2379,8 +2435,8 @@ graphql-relay = [
     {file = "graphql_relay-2.0.1-py3-none-any.whl", hash = "sha256:ac514cb86db9a43014d7e73511d521137ac12cf0101b2eaa5f0a3da2e10d913d"},
 ]
 idna = [
-    {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
-    {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
+    {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
+    {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
 ]
 immutables = [
     {file = "immutables-0.16-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:acbfa79d44228d96296279068441f980dc63dbed52522d9227ff9f4d96c6627e"},
@@ -2416,8 +2472,8 @@ importlib-metadata = [
     {file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"},
 ]
 importlib-resources = [
-    {file = "importlib_resources-5.2.2-py3-none-any.whl", hash = "sha256:2480d8e07d1890056cb53c96e3de44fead9c62f2ba949b0f2e4c4345f4afa977"},
-    {file = "importlib_resources-5.2.2.tar.gz", hash = "sha256:a65882a4d0fe5fbf702273456ba2ce74fe44892c25e42e057aca526b702a6d4b"},
+    {file = "importlib_resources-5.4.0-py3-none-any.whl", hash = "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45"},
+    {file = "importlib_resources-5.4.0.tar.gz", hash = "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b"},
 ]
 inflection = [
     {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"},
@@ -2428,6 +2484,9 @@ invoke = [
     {file = "invoke-1.6.0-py3-none-any.whl", hash = "sha256:769e90caeb1bd07d484821732f931f1ad8916a38e3f3e618644687fc09cb6317"},
     {file = "invoke-1.6.0.tar.gz", hash = "sha256:374d1e2ecf78981da94bfaf95366216aaec27c2d6a7b7d5818d92da55aa258d3"},
 ]
+ipaddr = [
+    {file = "ipaddr-2.2.0.tar.gz", hash = "sha256:4092dfe667588d16aa12b59acb7c8a4024e5dcb23a681cd0b0b602373eca88d6"},
+]
 isort = [
     {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"},
     {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"},
@@ -2445,8 +2504,8 @@ jsonschema = [
     {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
 ]
 junos-eznc = [
-    {file = "junos-eznc-2.5.4.tar.gz", hash = "sha256:bf036d0af9ee5c5e4f517cb5fc902fe891fa120e18f459805862c53d4a97193a"},
-    {file = "junos_eznc-2.5.4-py2.py3-none-any.whl", hash = "sha256:e05c36d56d8b8d13b1fb3bb763828bb3ee80fa1dcadc3a6762e8e2568504676d"},
+    {file = "junos-eznc-2.6.3.tar.gz", hash = "sha256:4eee93d0af203af7cee54a8f0c7bd28af683e829edf1fd68feba85d0ad737395"},
+    {file = "junos_eznc-2.6.3-py2.py3-none-any.whl", hash = "sha256:353fbe230a21caa021d37a0f840b09a9748a4f3d9689f46222200c3853d9bd20"},
 ]
 kiwisolver = [
     {file = "kiwisolver-1.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd34fbbfbc40628200730bc1febe30631347103fc8d3d4fa012c21ab9c11eca9"},
@@ -2520,54 +2579,66 @@ loguru = [
     {file = "loguru-0.5.3.tar.gz", hash = "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319"},
 ]
 lxml = [
-    {file = "lxml-4.6.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:df7c53783a46febb0e70f6b05df2ba104610f2fb0d27023409734a3ecbb78fb2"},
-    {file = "lxml-4.6.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1b7584d421d254ab86d4f0b13ec662a9014397678a7c4265a02a6d7c2b18a75f"},
-    {file = "lxml-4.6.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:079f3ae844f38982d156efce585bc540c16a926d4436712cf4baee0cce487a3d"},
-    {file = "lxml-4.6.3-cp27-cp27m-win32.whl", hash = "sha256:bc4313cbeb0e7a416a488d72f9680fffffc645f8a838bd2193809881c67dd106"},
-    {file = "lxml-4.6.3-cp27-cp27m-win_amd64.whl", hash = "sha256:8157dadbb09a34a6bd95a50690595e1fa0af1a99445e2744110e3dca7831c4ee"},
-    {file = "lxml-4.6.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7728e05c35412ba36d3e9795ae8995e3c86958179c9770e65558ec3fdfd3724f"},
-    {file = "lxml-4.6.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4"},
-    {file = "lxml-4.6.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:64812391546a18896adaa86c77c59a4998f33c24788cadc35789e55b727a37f4"},
-    {file = "lxml-4.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c1a40c06fd5ba37ad39caa0b3144eb3772e813b5fb5b084198a985431c2f1e8d"},
-    {file = "lxml-4.6.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51"},
-    {file = "lxml-4.6.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f90ba11136bfdd25cae3951af8da2e95121c9b9b93727b1b896e3fa105b2f586"},
-    {file = "lxml-4.6.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:4c61b3a0db43a1607d6264166b230438f85bfed02e8cff20c22e564d0faff354"},
-    {file = "lxml-4.6.3-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:5c8c163396cc0df3fd151b927e74f6e4acd67160d6c33304e805b84293351d16"},
-    {file = "lxml-4.6.3-cp35-cp35m-win32.whl", hash = "sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2"},
-    {file = "lxml-4.6.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4"},
-    {file = "lxml-4.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4"},
-    {file = "lxml-4.6.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3"},
-    {file = "lxml-4.6.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d"},
-    {file = "lxml-4.6.3-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d916d31fd85b2f78c76400d625076d9124de3e4bda8b016d25a050cc7d603f24"},
-    {file = "lxml-4.6.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec"},
-    {file = "lxml-4.6.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:c47ff7e0a36d4efac9fd692cfa33fbd0636674c102e9e8d9b26e1b93a94e7617"},
-    {file = "lxml-4.6.3-cp36-cp36m-win32.whl", hash = "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04"},
-    {file = "lxml-4.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a"},
-    {file = "lxml-4.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654"},
-    {file = "lxml-4.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0"},
-    {file = "lxml-4.6.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3"},
-    {file = "lxml-4.6.3-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:36108c73739985979bf302006527cf8a20515ce444ba916281d1c43938b8bb96"},
-    {file = "lxml-4.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2"},
-    {file = "lxml-4.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:cdaf11d2bd275bf391b5308f86731e5194a21af45fbaaaf1d9e8147b9160ea92"},
-    {file = "lxml-4.6.3-cp37-cp37m-win32.whl", hash = "sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade"},
-    {file = "lxml-4.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b"},
-    {file = "lxml-4.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa"},
-    {file = "lxml-4.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a"},
-    {file = "lxml-4.6.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927"},
-    {file = "lxml-4.6.3-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:e1cbd3f19a61e27e011e02f9600837b921ac661f0c40560eefb366e4e4fb275e"},
-    {file = "lxml-4.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791"},
-    {file = "lxml-4.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:1b38116b6e628118dea5b2186ee6820ab138dbb1e24a13e478490c7db2f326ae"},
-    {file = "lxml-4.6.3-cp38-cp38-win32.whl", hash = "sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28"},
-    {file = "lxml-4.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7"},
-    {file = "lxml-4.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0"},
-    {file = "lxml-4.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1"},
-    {file = "lxml-4.6.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23"},
-    {file = "lxml-4.6.3-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:3082c518be8e97324390614dacd041bb1358c882d77108ca1957ba47738d9d59"},
-    {file = "lxml-4.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969"},
-    {file = "lxml-4.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:6f12e1427285008fd32a6025e38e977d44d6382cf28e7201ed10d6c1698d2a9a"},
-    {file = "lxml-4.6.3-cp39-cp39-win32.whl", hash = "sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f"},
-    {file = "lxml-4.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83"},
-    {file = "lxml-4.6.3.tar.gz", hash = "sha256:39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468"},
+    {file = "lxml-4.6.4-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bbf2dc330bd44bfc0254ab37677ec60f7c7ecea55ad8ba1b8b2ea7bf20c265f5"},
+    {file = "lxml-4.6.4-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b667c51682fe9b9788c69465956baa8b6999531876ccedcafc895c74ad716cd8"},
+    {file = "lxml-4.6.4-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:72e730d33fe2e302fd07285f14624fca5e5e2fb2bb4fb2c3941e318c41c443d1"},
+    {file = "lxml-4.6.4-cp27-cp27m-win32.whl", hash = "sha256:433df8c7dde0f9e41cbf4f36b0829d50a378116ef5e962ba3881f2f5f025c7be"},
+    {file = "lxml-4.6.4-cp27-cp27m-win_amd64.whl", hash = "sha256:35752ee40f7bbf6adc9ff4e1f4b84794a3593736dcce80db32e3c2aa85e294ac"},
+    {file = "lxml-4.6.4-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ff5bb2a198ea67403bb6818705e9a4f90e0313f2215428ec51001ce56d939fb"},
+    {file = "lxml-4.6.4-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9b87727561c1150c0cc91c5d9d389448b37a7d15f0ba939ed3d1acb2f11bf6c5"},
+    {file = "lxml-4.6.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:45fdb2899c755138722797161547a40b3e2a06feda620cc41195ee7e97806d81"},
+    {file = "lxml-4.6.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:38b9de0de3aa689fe9fb9877ae1be1e83b8cf9621f7e62049d0436b9ecf4ad64"},
+    {file = "lxml-4.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:662523cd2a0246740225c7e32531f2e766544122e58bee70e700a024cfc0cf81"},
+    {file = "lxml-4.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:4aa349c5567651f34d4eaae7de6ed5b523f6d70a288f9c6fbac22d13a0784e04"},
+    {file = "lxml-4.6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:08eb9200d88b376a8ed5e50f1dc1d1a45b49305169674002a3b5929943390591"},
+    {file = "lxml-4.6.4-cp310-cp310-win32.whl", hash = "sha256:bdc224f216ead849e902151112efef6e96c41ee1322e15d4e5f7c8a826929aee"},
+    {file = "lxml-4.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:ab6db93a2b6b66cbf62b4e4a7135f476e708e8c5c990d186584142c77d7f975a"},
+    {file = "lxml-4.6.4-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:50790313df028aa05cf22be9a8da033b86c42fa32523e4fd944827b482b17bf0"},
+    {file = "lxml-4.6.4-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6764998345552b1dfc9326a932d2bad6367c6b37a176bb73ada6b9486bf602f7"},
+    {file = "lxml-4.6.4-cp35-cp35m-win32.whl", hash = "sha256:543b239b191bb3b6d9bef5f09f1fb2be5b7eb09ab4d386aa655e4d53fbe9ff47"},
+    {file = "lxml-4.6.4-cp35-cp35m-win_amd64.whl", hash = "sha256:a75c1ad05eedb1a3ff2a34a52a4f0836cfaa892e12796ba39a7732c82701eff4"},
+    {file = "lxml-4.6.4-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:47e955112ce64241fdb357acf0216081f9f3255b3ac9c502ca4b3323ec1ca558"},
+    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:20d7c8d90d449c6a353b15ee0459abae8395dbe59ad01e406ccbf30cd81c6f98"},
+    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:240db6f3228d26e3c6f4fad914b9ddaaf8707254e8b3efd564dc680c8ec3c264"},
+    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:351482da8dd028834028537f08724b1de22d40dcf3bb723b469446564f409074"},
+    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e678a643177c0e5ec947b645fa7bc84260dfb9b6bf8fb1fdd83008dfc2ca5928"},
+    {file = "lxml-4.6.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:15d0381feb56f08f78c5cc4fc385ddfe0bde1456e37f54a9322833371aec4060"},
+    {file = "lxml-4.6.4-cp36-cp36m-win32.whl", hash = "sha256:4ba74afe5ee5cb5e28d83b513a6e8f0875fda1dc1a9aea42cc0065f029160d2a"},
+    {file = "lxml-4.6.4-cp36-cp36m-win_amd64.whl", hash = "sha256:9c91a73971a922c13070fd8fa5a114c858251791ba2122a941e6aa781c713e44"},
+    {file = "lxml-4.6.4-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:6020c70ff695106bf80651953a23e37718ef1fee9abd060dcad8e32ab2dc13f3"},
+    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f5dd358536b8a964bf6bd48de038754c1609e72e5f17f5d21efe2dda17594dbf"},
+    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7ae7089d81fc502df4b217ad77f03c54039fe90dac0acbe70448d7e53bfbc57e"},
+    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:80d10d53d3184837445ff8562021bdd37f57c4cadacbf9d8726cc16220a00d54"},
+    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e95da348d57eb448d226a44b868ff2ca5786fbcbe417ac99ff62d0a7d724b9c7"},
+    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ffd65cfa33fed01735c82aca640fde4cc63f0414775cba11e06f84fae2085a6e"},
+    {file = "lxml-4.6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:877666418598f6cb289546c77ff87590cfd212f903b522b0afa0b9fb73b3ccfb"},
+    {file = "lxml-4.6.4-cp37-cp37m-win32.whl", hash = "sha256:e91d24623e747eeb2d8121f4a94c6a7ad27dc48e747e2dc95bfe88632bd028a2"},
+    {file = "lxml-4.6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4ec9a80dd5704ecfde54319b6964368daf02848c8954d3bacb9b64d1c7659159"},
+    {file = "lxml-4.6.4-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:2901625f4a878a055d275beedc20ba9cb359cefc4386a967222fee29eb236038"},
+    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b567178a74a2261345890eac66fbf394692a6e002709d329f28a673ca6042473"},
+    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4717123f7c11c81e0da69989e5a64079c3f402b0efeb4c6241db6c369d657bd8"},
+    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:cf201bf5594d1aab139fe53e3fca457e4f8204a5bbd65d48ab3b82a16f517868"},
+    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a77a3470ba37e11872c75ca95baf9b3312133a3d5a5dc720803b23098c653976"},
+    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:619c6d2b552bba00491e96c0518aad94002651c108a0f7364ff2d7798812c00e"},
+    {file = "lxml-4.6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:601f0ab75538b280aaf1e720eb9d68d4fa104ac274e1e9e6971df488f4dcdb0f"},
+    {file = "lxml-4.6.4-cp38-cp38-win32.whl", hash = "sha256:75d3c5bbc0ddbad03bb68b9be638599f67e4b98ed3dcd0fec9f6f39e41ee96cb"},
+    {file = "lxml-4.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:4341d135f5660db10184963d9c3418c3e28d7f868aaf8b11a323ebf85813f7f4"},
+    {file = "lxml-4.6.4-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:9db24803fa71e3305fe4a7812782b708da21a0b774b130dd1860cf40a6d7a3ee"},
+    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:afd60230ad9d8bcba005945ec3a343722f09e0b7f8ae804246e5d2cfc6bd71a6"},
+    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:0c15e1cd55055956e77b0732270f1c6005850696bc3ef3e03d01e78af84eaa42"},
+    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6d422b3c729737d8a39279a25fa156c983a56458f8b2f97661ee6fb22b80b1d6"},
+    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2eb90f6ec3c236ef2f1bb38aee7c0d23e77d423d395af6326e7cca637519a4cb"},
+    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:51a0e5d243687596f46e24e464121d4b232ad772e2d1785b2a2c0eb413c285d4"},
+    {file = "lxml-4.6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d43bd68714049c84e297c005456a15ecdec818f7b5aa5868c8b0a865cfb78a44"},
+    {file = "lxml-4.6.4-cp39-cp39-win32.whl", hash = "sha256:ee9e4b07b0eba4b6a521509e9e1877476729c1243246b6959de697ebea739643"},
+    {file = "lxml-4.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:48eaac2991b3036175b42ee8d3c23f4cca13f2be8426bf29401a690ab58c88f4"},
+    {file = "lxml-4.6.4-pp37-pypy37_pp73-macosx_10_14_x86_64.whl", hash = "sha256:2b06a91cf7b8acea7793006e4ae50646cef0fe35ce5acd4f5cb1c77eb228e4a1"},
+    {file = "lxml-4.6.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:523f195948a1ba4f9f5b7294d83c6cd876547dc741820750a7e5e893a24bbe38"},
+    {file = "lxml-4.6.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b0ca0ada9d3bc18bd6f611bd001a28abdd49ab9698bd6d717f7f5394c8e94628"},
+    {file = "lxml-4.6.4-pp38-pypy38_pp73-macosx_10_14_x86_64.whl", hash = "sha256:197b7cb7a753cf553a45115739afd8458464a28913da00f5c525063f94cd3f48"},
+    {file = "lxml-4.6.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:6298f5b42a26581206ef63fffa97c754245d329414108707c525512a5197f2ba"},
+    {file = "lxml-4.6.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0b12c95542f04d10cba46b3ff28ea52ea56995b78cf918f0b11b05e75812bb79"},
+    {file = "lxml-4.6.4.tar.gz", hash = "sha256:daf9bd1fee31f1c7a5928b3e1059e09a8d683ea58fb3ffc773b6c88cb8d1399c"},
 ]
 markdown = [
     {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"},
@@ -2579,6 +2650,9 @@ markupsafe = [
     {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"},
     {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"},
     {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"},
+    {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"},
+    {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"},
+    {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"},
     {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"},
     {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"},
     {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"},
@@ -2590,6 +2664,9 @@ markupsafe = [
     {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"},
     {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"},
     {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"},
+    {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"},
+    {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"},
+    {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"},
     {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"},
     {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"},
     {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"},
@@ -2601,6 +2678,9 @@ markupsafe = [
     {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"},
     {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"},
     {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"},
+    {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"},
+    {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"},
+    {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"},
     {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"},
     {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"},
     {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"},
@@ -2613,6 +2693,9 @@ markupsafe = [
     {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"},
     {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"},
     {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"},
+    {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"},
+    {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"},
+    {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"},
     {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"},
     {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"},
     {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"},
@@ -2625,6 +2708,9 @@ markupsafe = [
     {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"},
     {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"},
     {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"},
+    {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"},
+    {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"},
+    {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"},
     {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"},
     {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
     {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
@@ -2669,15 +2755,15 @@ napalm = [
     {file = "napalm-3.3.1.tar.gz", hash = "sha256:6fe46d5b4ca761a2bde8ea2bea3e0b808a907afc808c6c67178060eb323320e8"},
 ]
 nautobot = [
-    {file = "nautobot-1.1.3-py3-none-any.whl", hash = "sha256:826cb6b9ba97e06c6085fc8fec9436ec69590fab4ad17d9a02dbeb6347af1714"},
-    {file = "nautobot-1.1.3.tar.gz", hash = "sha256:497a0ed6ab6e31566e831650d328b77db999aca161caa3ab98357351de8c87bd"},
+    {file = "nautobot-1.1.4-py3-none-any.whl", hash = "sha256:355773e30aa2d7da187e610751691cb0bde5314933a14d45c3e140c6410d718f"},
+    {file = "nautobot-1.1.4.tar.gz", hash = "sha256:a4feff233bf7255a1deadb025c023a96b97a18a3cf676af151ea02c2896b709c"},
 ]
 nautobot-plugin-nornir = [
-    {file = "nautobot-plugin-nornir-0.9.4.tar.gz", hash = "sha256:08217646a5b8c973c9379f51a9633d8b5962e95cb28afd4cfde52c3b5ce9204a"},
-    {file = "nautobot_plugin_nornir-0.9.4-py3-none-any.whl", hash = "sha256:87c8863229e83a12e99aa302eaf5f9489835b8c45ea434cf622d9cb4ea1136bc"},
+    {file = "nautobot-plugin-nornir-0.9.7.tar.gz", hash = "sha256:e71cdbce4a66e3f801cf4931034c5bc9fe8a4e4ca606a80286c286a480f04cd0"},
+    {file = "nautobot_plugin_nornir-0.9.7-py3-none-any.whl", hash = "sha256:5576aa1a8496991a3730ffacf551e708fb54abe480225b6521df9253c9086241"},
 ]
 ncclient = [
-    {file = "ncclient-0.6.12.tar.gz", hash = "sha256:37c8a9f9a44f0346144119ab17ae6559e44b5a991f4c34ea3765c678079e4beb"},
+    {file = "ncclient-0.6.9.tar.gz", hash = "sha256:0112f2ad41fb658f52446d870853a63691d69299c73c7351c520d38dbd8dc0c4"},
 ]
 netaddr = [
     {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"},
@@ -2688,8 +2774,8 @@ netmiko = [
     {file = "netmiko-3.4.0.tar.gz", hash = "sha256:acadb9dd97864ee848e2032f1f0e301c7b31e7a4153757d98f5c8ba1b9614993"},
 ]
 netutils = [
-    {file = "netutils-0.2.2-py3-none-any.whl", hash = "sha256:a0335a8d7e5210877cdc9017d2984a0abef23529b8f0147915f0ea5147b6a2c3"},
-    {file = "netutils-0.2.2.tar.gz", hash = "sha256:b848ed9536e13931761ec641346f5330e18f78a91d880253cf86d860a084555b"},
+    {file = "netutils-0.2.5-py3-none-any.whl", hash = "sha256:6715b0e1175051f5db7685bf057ede68c7dafc56cf705a1ca3896e24980b22ce"},
+    {file = "netutils-0.2.5.tar.gz", hash = "sha256:bdfd8e454c4aeacf59c1537bfd434e1d944ce69032fed533f0171c2532c91751"},
 ]
 nornir = [
     {file = "nornir-3.1.1-py3-none-any.whl", hash = "sha256:217199f923c810f4a54dec8d440eb08682c8a4ea4746325bd3067dca2e32cf9f"},
@@ -2704,8 +2790,8 @@ nornir-napalm = [
     {file = "nornir_napalm-0.1.2.tar.gz", hash = "sha256:be7808a990242987500a65701edb626197c5d0b87f35d9eb5da7ce7e4d60fdd5"},
 ]
 nornir-nautobot = [
-    {file = "nornir-nautobot-2.1.0.tar.gz", hash = "sha256:6da911dddd50d734cd6ad70f3f87a9c3f9ec1f688b6268ccab9524f8d2a001f7"},
-    {file = "nornir_nautobot-2.1.0-py3-none-any.whl", hash = "sha256:bcbc72418043db158a1163b58ce683ab34d7d47ed67906ad1a374b5bc0c31809"},
+    {file = "nornir-nautobot-2.2.0.tar.gz", hash = "sha256:8bc5b7185c9dfbf31fa2177ec3e4bd93731aec63a11156d9b346c278f8f56abb"},
+    {file = "nornir_nautobot-2.2.0-py3-none-any.whl", hash = "sha256:3f3916330a8c8de773b70cd3fe14da0f4809c9298be221c94168bd11a5366591"},
 ]
 nornir-netmiko = [
     {file = "nornir_netmiko-0.1.1-py3-none-any.whl", hash = "sha256:c6eadb81f6f3b2f0c27bae151cc62673303f9d085ec3c773ecdc98f20ef30f91"},
@@ -2716,8 +2802,8 @@ nornir-utils = [
     {file = "nornir_utils-0.1.2.tar.gz", hash = "sha256:23ae95c4805b0ce8a5ed32935f3f86027e5701175e7740ab8b3a79946c5d90b2"},
 ]
 ntc-templates = [
-    {file = "ntc_templates-2.3.2-py3-none-any.whl", hash = "sha256:1a957a4ecc0a0091c91b20e8fa36cc9c07f7c40fbe9ac96428452fe733c2069d"},
-    {file = "ntc_templates-2.3.2.tar.gz", hash = "sha256:5c09282ee98a3970904b3cbbfda861a83a14b023e7aaf5a88e711b5dfd4a16a7"},
+    {file = "ntc_templates-3.0.0-py3-none-any.whl", hash = "sha256:a652ff1659803d98fc088fc1b0838a74533316b0ad627c1220c0424dd82d12b3"},
+    {file = "ntc_templates-3.0.0.tar.gz", hash = "sha256:866c1b57af48625e1a38cc7226067e400d8a992c4d5594b914cafd7b13fd4a50"},
 ]
 numpy = [
     {file = "numpy-1.19.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc6bd4fd593cb261332568485e20a0712883cf631f6f5e8e86a52caa8b2b50ff"},
@@ -2763,12 +2849,12 @@ ordered-set = [
     {file = "ordered-set-4.0.2.tar.gz", hash = "sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95"},
 ]
 packaging = [
-    {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"},
-    {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"},
+    {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
+    {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
 ]
 paramiko = [
-    {file = "paramiko-2.7.2-py2.py3-none-any.whl", hash = "sha256:4f3e316fef2ac628b05097a637af35685183111d4bc1b5979bd397c2ab7b5898"},
-    {file = "paramiko-2.7.2.tar.gz", hash = "sha256:7f36f4ba2c0d81d219f4595e35f70d56cc94f9ac40a6acdf51d6ca210ce65035"},
+    {file = "paramiko-2.8.0-py2.py3-none-any.whl", hash = "sha256:def3ec612399bab4e9f5eb66b0ae5983980db9dd9120d9e9c6ea3ff673865d1c"},
+    {file = "paramiko-2.8.0.tar.gz", hash = "sha256:e673b10ee0f1c80d46182d3af7751d033d9b573dd7054d2d0aa46be186c3c1d2"},
 ]
 passlib = [
     {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"},
@@ -2779,8 +2865,8 @@ pathspec = [
     {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
 ]
 pbr = [
-    {file = "pbr-5.6.0-py2.py3-none-any.whl", hash = "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4"},
-    {file = "pbr-5.6.0.tar.gz", hash = "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd"},
+    {file = "pbr-5.8.0-py2.py3-none-any.whl", hash = "sha256:176e8560eaf61e127817ef93d8a844803abb27a4d4637f0ff3bb783129be2e0a"},
+    {file = "pbr-5.8.0.tar.gz", hash = "sha256:672d8ebee84921862110f23fcec2acea191ef58543d34dfe9ef3d9f13c31cddf"},
 ]
 pillow = [
     {file = "Pillow-8.3.2-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:c691b26283c3a31594683217d746f1dad59a7ae1d4cfc24626d7a064a11197d4"},
@@ -2837,9 +2923,13 @@ pillow = [
     {file = "Pillow-8.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ce651ca46d0202c302a535d3047c55a0131a720cf554a578fc1b8a2aff0e7d96"},
     {file = "Pillow-8.3.2.tar.gz", hash = "sha256:dde3f3ed8d00c72631bc19cbfff8ad3b6215062a5eed402381ad365f82f0c18c"},
 ]
+platformdirs = [
+    {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"},
+    {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"},
+]
 prometheus-client = [
-    {file = "prometheus_client-0.11.0-py2.py3-none-any.whl", hash = "sha256:b014bc76815eb1399da8ce5fc84b7717a3e63652b0c0f8804092c9363acab1b2"},
-    {file = "prometheus_client-0.11.0.tar.gz", hash = "sha256:3a8baade6cb80bcfe43297e33e7623f3118d660d41387593758e2fb1ea173a86"},
+    {file = "prometheus_client-0.12.0-py2.py3-none-any.whl", hash = "sha256:317453ebabff0a1b02df7f708efbab21e3489e7072b61cb6957230dd004a0af0"},
+    {file = "prometheus_client-0.12.0.tar.gz", hash = "sha256:1b12ba48cee33b9b0b9de64a1047cbd3c5f2d0ab6ebcead7ddda613a750ec3c5"},
 ]
 promise = [
     {file = "promise-2.3.tar.gz", hash = "sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"},
@@ -2886,63 +2976,63 @@ psycopg2-binary = [
     {file = "psycopg2_binary-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6"},
 ]
 pycodestyle = [
-    {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
-    {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
+    {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
+    {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
 ]
 pycparser = [
-    {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
-    {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
+    {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
+    {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
 ]
 pycryptodome = [
-    {file = "pycryptodome-3.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1c5e1ca507de2ad93474be5cfe2bfa76b7cf039a1a32fc196f40935944871a06"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:6260e24d41149268122dd39d4ebd5941e9d107f49463f7e071fd397e29923b0c"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3f840c49d38986f6e17dbc0673d37947c88bc9d2d9dba1c01b979b36f8447db1"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:2dea65df54349cdfa43d6b2e8edb83f5f8d6861e5cf7b1fbc3e34c5694c85e27"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:e61e363d9a5d7916f3a4ce984a929514c0df3daf3b1b2eb5e6edbb131ee771cf"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:2603c98ae04aac675fefcf71a6c87dc4bb74a75e9071ae3923bbc91a59f08d35"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-win32.whl", hash = "sha256:38661348ecb71476037f1e1f553159b80d256c00f6c0b00502acac891f7116d9"},
-    {file = "pycryptodome-3.10.1-cp27-cp27m-win_amd64.whl", hash = "sha256:1723ebee5561628ce96748501cdaa7afaa67329d753933296321f0be55358dce"},
-    {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:77997519d8eb8a4adcd9a47b9cec18f9b323e296986528186c0e9a7a15d6a07e"},
-    {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:99b2f3fc51d308286071d0953f92055504a6ffe829a832a9fc7a04318a7683dd"},
-    {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e0a4d5933a88a2c98bbe19c0c722f5483dc628d7a38338ac2cb64a7dbd34064b"},
-    {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d3d6958d53ad307df5e8469cc44474a75393a434addf20ecd451f38a72fe29b8"},
-    {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:a8eb8b6ea09ec1c2535bf39914377bc8abcab2c7d30fa9225eb4fe412024e427"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:31c1df17b3dc5f39600a4057d7db53ac372f492c955b9b75dd439f5d8b460129"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-manylinux1_i686.whl", hash = "sha256:a3105a0eb63eacf98c2ecb0eb4aa03f77f40fbac2bdde22020bb8a536b226bb8"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:a92d5c414e8ee1249e850789052608f582416e82422502dc0ac8c577808a9067"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:60386d1d4cfaad299803b45a5bc2089696eaf6cdd56f9fc17479a6f89595cfc8"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:501ab36aae360e31d0ec370cf5ce8ace6cb4112060d099b993bc02b36ac83fb6"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:fc7489a50323a0df02378bc2fff86eb69d94cc5639914346c736be981c6a02e7"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-win32.whl", hash = "sha256:9b6f711b25e01931f1c61ce0115245a23cdc8b80bf8539ac0363bdcf27d649b6"},
-    {file = "pycryptodome-3.10.1-cp35-abi3-win_amd64.whl", hash = "sha256:7fd519b89585abf57bf47d90166903ec7b43af4fe23c92273ea09e6336af5c07"},
-    {file = "pycryptodome-3.10.1-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:09c1555a3fa450e7eaca41ea11cd00afe7c91fef52353488e65663777d8524e0"},
-    {file = "pycryptodome-3.10.1-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:758949ca62690b1540dfb24ad773c6da9cd0e425189e83e39c038bbd52b8e438"},
-    {file = "pycryptodome-3.10.1-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:e3bf558c6aeb49afa9f0c06cee7fb5947ee5a1ff3bd794b653d39926b49077fa"},
-    {file = "pycryptodome-3.10.1-pp27-pypy_73-win32.whl", hash = "sha256:f977cdf725b20f6b8229b0c87acb98c7717e742ef9f46b113985303ae12a99da"},
-    {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6d2df5223b12437e644ce0a3be7809471ffa71de44ccd28b02180401982594a6"},
-    {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:98213ac2b18dc1969a47bc65a79a8fca02a414249d0c8635abb081c7f38c91b6"},
-    {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:12222a5edc9ca4a29de15fbd5339099c4c26c56e13c2ceddf0b920794f26165d"},
-    {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:6bbf7fee7b7948b29d7e71fcacf48bac0c57fb41332007061a933f2d996f9713"},
-    {file = "pycryptodome-3.10.1.tar.gz", hash = "sha256:3e2e3a06580c5f190df843cdb90ea28d61099cf4924334d5297a995de68e4673"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:91ba4215a1f37d0f371fe43bc88c5ff49c274849f3868321c889313787de7672"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:66301e4c42dee43ee2da256625d3fe81ef98cc9924c2bd535008cc3ad8ded77b"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:8ec154ec445412df31acf0096e7f715e30e167c8f2318b8f5b1ab7c28f4c82f7"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:8e82524e7c354033508891405574d12e612cc4fdd3b55d2c238fc1a3e300b606"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:b217b4525e60e1af552d62bec01b4685095436d4de5ecde0f05d75b2f95ba6d4"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:3a153658d97258ca20bf18f7fe31c09cc7c558b6f8974a6ec74e19f6c634bd64"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-win32.whl", hash = "sha256:c6469d1453f5864e3321a172b0aa671b938d753cbf2376b99fa2ab8841539bb8"},
+    {file = "pycryptodome-3.10.4-cp27-cp27m-win_amd64.whl", hash = "sha256:6b45fcace5a5d9c57ba87cf804b161adc62aa826295ce7f7acbcbdc0df74ed37"},
+    {file = "pycryptodome-3.10.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:b1daf251395af7336ddde6a0015ba5e632c18fe646ba930ef87402537358e3b4"},
+    {file = "pycryptodome-3.10.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9a2312440057bf29b9582f72f14d79692044e63bfbc4b4bbea8559355f44f3dd"},
+    {file = "pycryptodome-3.10.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:54d4e4d45f349d8c4e2f31c2734637ff62a844af391b833f789da88e43a8f338"},
+    {file = "pycryptodome-3.10.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:97e7df67a4da2e3f60612bbfd6c3f243a63a15d8f4797dd275e1d7b44a65cb12"},
+    {file = "pycryptodome-3.10.4-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:db15fa07d2a4c00beeb5e9acdfdbc1c79f9ccfbdc1a8f36c82c4aa44951b33c9"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:217dcc0c92503f7dd4b3d3b7d974331a4419f97f555c99a845c3b366fed7056b"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-manylinux1_i686.whl", hash = "sha256:a7471646d8cd1a58bb696d667dcb3853e5c9b341b68dcf3c3cc0893d0f98ca5f"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:d713dc0910e5ded07852a05e9b75f1dd9d3a31895eebee0668f612779b2a748c"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:ac3012c36633564b2b5539bb7c6d9175f31d2ce74844e9abe654c428f02d0fd8"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:3f9fb499e267039262569d08658132c9cd8b136bf1d8c56b72f70ed05551e526"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:309529d2526f3fb47102aeef376b3459110a6af7efb162e860b32e3a17a46f06"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-win32.whl", hash = "sha256:7efec2418e9746ec48e264eea431f8e422d931f71c57b1c96ee202b117f58fa9"},
+    {file = "pycryptodome-3.10.4-cp35-abi3-win_amd64.whl", hash = "sha256:49e54f2245befb0193848c8c8031d8d1358ed4af5a1ae8d0a3ba669a5cdd3a72"},
+    {file = "pycryptodome-3.10.4-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:4e8fc4c48365ce8a542fe48bf1360da05bb2851df12f64fc94d751705e7cdbe7"},
+    {file = "pycryptodome-3.10.4-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:851e6d4930b160417235955322db44adbdb19589918670d63f4acd5d92959ac0"},
+    {file = "pycryptodome-3.10.4-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:04e14c732c3693d2830839feed5129286ce47ffa8bfe90e4ae042c773e51c677"},
+    {file = "pycryptodome-3.10.4-pp27-pypy_73-win32.whl", hash = "sha256:cefe6b267b8e5c3c72e11adec35a9c7285b62e8ea141b63e87055e9a9e5f2f8c"},
+    {file = "pycryptodome-3.10.4-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:24c1b7705d19d8ae3e7255431efd2e526006855df62620118dd7b5374c6372f6"},
+    {file = "pycryptodome-3.10.4-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:c61ea053bd5d4c12a063d7e704fbe1c45abb5d2510dab55bd95d166ba661604f"},
+    {file = "pycryptodome-3.10.4-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:11d3164fb49fdee000fde05baecce103c0c698168ef1a18d9c7429dd66f0f5bb"},
+    {file = "pycryptodome-3.10.4-pp36-pypy36_pp73-win32.whl", hash = "sha256:3faa6ebd35c61718f3f8862569c1f38450c24f3ededb213e1a64806f02f584bc"},
+    {file = "pycryptodome-3.10.4.tar.gz", hash = "sha256:40083b0d7f277452c7f2dd4841801f058cc12a74c219ee4110d65774c6a58bef"},
 ]
 pydocstyle = [
-    {file = "pydocstyle-5.1.1-py3-none-any.whl", hash = "sha256:aca749e190a01726a4fb472dd4ef23b5c9da7b9205c0a7857c06533de13fd678"},
-    {file = "pydocstyle-5.1.1.tar.gz", hash = "sha256:19b86fa8617ed916776a11cd8bc0197e5b9856d5433b777f51a3defe13075325"},
+    {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"},
+    {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"},
 ]
 pyeapi = [
     {file = "pyeapi-0.8.4.tar.gz", hash = "sha256:c33ad1eadd8ebac75f63488df9412081ce0b024c9e1da12a37196a5c60427c54"},
 ]
 pyflakes = [
-    {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
-    {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
+    {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
+    {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
 ]
 pyjwt = [
-    {file = "PyJWT-2.1.0-py3-none-any.whl", hash = "sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1"},
-    {file = "PyJWT-2.1.0.tar.gz", hash = "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130"},
+    {file = "PyJWT-2.3.0-py3-none-any.whl", hash = "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f"},
+    {file = "PyJWT-2.3.0.tar.gz", hash = "sha256:b888b4d56f06f6dcd777210c334e69c737be74755d3e5e9ee3fe67dc18a0ee41"},
 ]
 pylint = [
-    {file = "pylint-2.7.4-py3-none-any.whl", hash = "sha256:209d712ec870a0182df034ae19f347e725c1e615b2269519ab58a35b3fcbbe7a"},
-    {file = "pylint-2.7.4.tar.gz", hash = "sha256:bd38914c7731cdc518634a8d3c5585951302b6e2b6de60fbb3f7a0220e21eeee"},
+    {file = "pylint-2.12.0-py3-none-any.whl", hash = "sha256:ba00afcb1550bc217bbcb0eb76c10cb8335f7417a3323bdd980c29fb5b59f8d2"},
+    {file = "pylint-2.12.0.tar.gz", hash = "sha256:245c87e5da54c35b623c21b35debf87d93b18bf9e0229515cc172d0b83d627cd"},
 ]
 pylint-django = [
     {file = "pylint-django-2.4.4.tar.gz", hash = "sha256:f63f717169b0c2e4e19c28f1c32c28290647330184fcb7427805ae9b6994f3fc"},
@@ -2977,8 +3067,8 @@ pynautobot = [
     {file = "pynautobot-1.0.3.tar.gz", hash = "sha256:01fc6cf32e6ad520c7847d304dde356890960a4d95de48af6a1ce1f43fac6a65"},
 ]
 pyparsing = [
-    {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
-    {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
+    {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
+    {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
 ]
 pyrsistent = [
     {file = "pyrsistent-0.18.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f4c8cabb46ff8e5d61f56a037974228e978f26bfefce4f61a4b1ac0ba7a2ab72"},
@@ -3016,24 +3106,36 @@ python3-openid = [
     {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"},
 ]
 pytz = [
-    {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
-    {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
+    {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
+    {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
 ]
 pyuwsgi = [
-    {file = "pyuwsgi-2.0.19.1.post0-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:a425f562f382a097ca49df26b70d47d12f0cf0abf233610f3f58b1f7f780355e"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:56ecda11e873b2eb937b33d2999766322eebfa82ee5b26a2196a335c4e786186"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:297d1d0b8c472374b12eda7f17a9f5de67cf516612e42b71a7636afb9d1e3974"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp35-cp35m-macosx_10_13_intel.whl", hash = "sha256:5439f0f3ef5d6bf1622f341662d04c1d92b88889db40b295419e5fe75a7c7d45"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:890e7e863cb61c8369b6bcfa5d6f323753aaeec2cfaba16741f119c79b964aa7"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:bddeb8df77010d0f842068765a0b3155fdcfd847f14bc1ba89fc7e37914a13d2"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:90e4235020048456ad867aefc383cdf5528b7f6e327555ceec579c428a828759"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:94d4287b155aa789ce4b6f671c981f7d6c58fc3113330e2f29ac7926cb854645"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:66a9751f28abf348e0ddccadc4ded47623f2d35cf9609c87b57909d55a4cdc15"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:285e263a9094389f13cfdefd033a4e99fbed3ad120dba9ac5093846cc03ac5ab"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:dac4a04dc0f69d641dba984e83214d2c2cc098496c5d5585e7d3f4e7a9190f84"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ac79dead0685beab5ecfe0926426849a44c5572528f89bb17f6ecf5eb561024e"},
-    {file = "pyuwsgi-2.0.19.1.post0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:149675b2e020b0e833e8b871a545751ca346cbfed85c8fd2b320a01d40dc3d8f"},
-    {file = "pyuwsgi-2.0.19.1.post0.tar.gz", hash = "sha256:0bd14517398f494d828d77a9bf72b5a6cbef0112e1cc05e9a0080fa8828ccfa0"},
+    {file = "pyuwsgi-2.0.20-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd09a7328558728f6e38f77609f44d16f18d8b4dc5f8b8776f657c8892b70337"},
+    {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:210ad768b8af02bbfd3c0345a51c6d2c56a2333ac268d9a97ecf2d4209f78ef8"},
+    {file = "pyuwsgi-2.0.20-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e33111308a79dbd202094963fd3a537dab30854e375d9be018f642fcd359e03d"},
+    {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dd048b85abb90c79a34afbf787995ab2933cb2a8b210a6e064e5fca0a9bdf2d8"},
+    {file = "pyuwsgi-2.0.20-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f612a72437c2934e39393fb575fab791e919efc102a0aa1a27b5d9a301d462e9"},
+    {file = "pyuwsgi-2.0.20-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:78ac2d8b7d307232f8276cb8a45300211b0fae179c0494f2a3e3178c70693f81"},
+    {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f84fc44bba77d05fa9d01189028501ff8e6a2d63db184ceea42085ce28196317"},
+    {file = "pyuwsgi-2.0.20-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:342c312949c2f494f5d9ac272965715483cb22ed0353c18abb1b4590769ef00f"},
+    {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:dc99724df6d5613300d3357c4017cde840830ca132fe98f0a4feab9a6af48622"},
+    {file = "pyuwsgi-2.0.20-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:70096084ccfa18f058dfb3380aa10e80d48958ddfdb888b827f06aacb72f80b8"},
+    {file = "pyuwsgi-2.0.20-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e7a8576452635612c82f660e5be99ba42cdcdff142948f5c263b5278f2c17b0"},
+    {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2844205e0095a29d3a6e9e23bd37bcf18d65e4e5ab23a14a45f5159c03a3b890"},
+    {file = "pyuwsgi-2.0.20-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e2c0d5dafb9faacc8ed5b662f9eacb22e723fbc3cb7152b2ebf09a92b8bd6c0d"},
+    {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:99b0c5a87aa95dcbaca2ccb599d783f37461600e098881d4ec9796ba68e3ff8f"},
+    {file = "pyuwsgi-2.0.20-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:df08a05dda4a92da46bd56af755dac091b145815c3cf6dda1855e01e40d12a99"},
+    {file = "pyuwsgi-2.0.20-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c8ac4b2f411d15222f53a96627b8fa79056b39606925f429f59a51668bd95ab"},
+    {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f1494d00df440865b1ee269a350187766c9c364ba5f124eddb064f366c4b6d8a"},
+    {file = "pyuwsgi-2.0.20-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5ee8782932dbacdb4dd98714c3575cbbb88ba87d7bcb3149c828725ba048897"},
+    {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:015a8d310503eb8c0028ac8f98c7df3b49bc937c7db137aaf149ca7fae64c777"},
+    {file = "pyuwsgi-2.0.20-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9fc3d256270adf24b87f1dff893f3bc59bd5ee20c4ebb5add25e944c36359e1e"},
+    {file = "pyuwsgi-2.0.20-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:052fe12d6a9ab9e9fc7814e40d2d28061aaea1a610069008d773e1d8a71feb11"},
+    {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7d160c7bfa8f2974fc6b807a8fc080be0d130b1a4ad0b463c0320e707e6a6eb6"},
+    {file = "pyuwsgi-2.0.20-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7691ca470e541133c444b23f83c6f07ecca12f4771a49e0e3a04b05f4c80f2d3"},
+    {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a8fc4d52232f55df16e9cbf6faf4bf16910d15042229d5f8c717278fd4ea37a5"},
+    {file = "pyuwsgi-2.0.20-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1acedb1841aa0e60e1a7245ae483a5fcb30e39cf0cdfe3987e14de4746daf75b"},
+    {file = "pyuwsgi-2.0.20.tar.gz", hash = "sha256:8b0936a964511fa0e2ac2847c2435e95130e7c98619f06fe1f67320527576043"},
 ]
 pyyaml = [
     {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
@@ -3067,51 +3169,84 @@ pyyaml = [
     {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
 ]
 redis = [
-    {file = "redis-3.5.3-py2.py3-none-any.whl", hash = "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"},
-    {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"},
+    {file = "redis-4.0.2-py3-none-any.whl", hash = "sha256:c8481cf414474e3497ec7971a1ba9b998c8efad0f0d289a009a5bbef040894f9"},
+    {file = "redis-4.0.2.tar.gz", hash = "sha256:ccf692811f2c1fc7a92b466aa2599e4a6d2d73d5f736a2c70be600657c0da34a"},
 ]
 regex = [
-    {file = "regex-2021.8.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2"},
-    {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a"},
-    {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f6a808044faae658f546dd5f525e921de9fa409de7a5570865467f03a626fc0"},
-    {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb"},
-    {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79aef6b5cd41feff359acaf98e040844613ff5298d0d19c455b3d9ae0bc8c35a"},
-    {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308"},
-    {file = "regex-2021.8.28-cp310-cp310-win32.whl", hash = "sha256:6eebf512aa90751d5ef6a7c2ac9d60113f32e86e5687326a50d7686e309f66ed"},
-    {file = "regex-2021.8.28-cp310-cp310-win_amd64.whl", hash = "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8"},
-    {file = "regex-2021.8.28-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c"},
-    {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c"},
-    {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328a1fad67445550b982caa2a2a850da5989fd6595e858f02d04636e7f8b0b13"},
-    {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0"},
-    {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66256b6391c057305e5ae9209941ef63c33a476b73772ca967d4a2df70520ec1"},
-    {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f"},
-    {file = "regex-2021.8.28-cp36-cp36m-win32.whl", hash = "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354"},
-    {file = "regex-2021.8.28-cp36-cp36m-win_amd64.whl", hash = "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645"},
-    {file = "regex-2021.8.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a"},
-    {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e"},
-    {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892"},
-    {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791"},
-    {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60667673ff9c249709160529ab39667d1ae9fd38634e006bec95611f632e759"},
-    {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906"},
-    {file = "regex-2021.8.28-cp37-cp37m-win32.whl", hash = "sha256:4cde065ab33bcaab774d84096fae266d9301d1a2f5519d7bd58fc55274afbf7a"},
-    {file = "regex-2021.8.28-cp37-cp37m-win_amd64.whl", hash = "sha256:1413b5022ed6ac0d504ba425ef02549a57d0f4276de58e3ab7e82437892704fc"},
-    {file = "regex-2021.8.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd"},
-    {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28fc475f560d8f67cc8767b94db4c9440210f6958495aeae70fac8faec631797"},
-    {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f"},
-    {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256"},
-    {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:808ee5834e06f57978da3e003ad9d6292de69d2bf6263662a1a8ae30788e080b"},
-    {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d5111d4c843d80202e62b4fdbb4920db1dcee4f9366d6b03294f45ed7b18b42e"},
-    {file = "regex-2021.8.28-cp38-cp38-win32.whl", hash = "sha256:473858730ef6d6ff7f7d5f19452184cd0caa062a20047f6d6f3e135a4648865d"},
-    {file = "regex-2021.8.28-cp38-cp38-win_amd64.whl", hash = "sha256:31a99a4796bf5aefc8351e98507b09e1b09115574f7c9dbb9cf2111f7220d2e2"},
-    {file = "regex-2021.8.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468"},
-    {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb"},
-    {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d"},
-    {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983"},
-    {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1743345e30917e8c574f273f51679c294effba6ad372db1967852f12c76759d8"},
-    {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed"},
-    {file = "regex-2021.8.28-cp39-cp39-win32.whl", hash = "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374"},
-    {file = "regex-2021.8.28-cp39-cp39-win_amd64.whl", hash = "sha256:610b690b406653c84b7cb6091facb3033500ee81089867ee7d59e675f9ca2b73"},
-    {file = "regex-2021.8.28.tar.gz", hash = "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1"},
+    {file = "regex-2021.11.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9345b6f7ee578bad8e475129ed40123d265464c4cfead6c261fd60fc9de00bcf"},
+    {file = "regex-2021.11.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:416c5f1a188c91e3eb41e9c8787288e707f7d2ebe66e0a6563af280d9b68478f"},
+    {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0538c43565ee6e703d3a7c3bdfe4037a5209250e8502c98f20fea6f5fdf2965"},
+    {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee1227cf08b6716c85504aebc49ac827eb88fcc6e51564f010f11a406c0a667"},
+    {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6650f16365f1924d6014d2ea770bde8555b4a39dc9576abb95e3cd1ff0263b36"},
+    {file = "regex-2021.11.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30ab804ea73972049b7a2a5c62d97687d69b5a60a67adca07eb73a0ddbc9e29f"},
+    {file = "regex-2021.11.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68a067c11463de2a37157930d8b153005085e42bcb7ad9ca562d77ba7d1404e0"},
+    {file = "regex-2021.11.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:162abfd74e88001d20cb73ceaffbfe601469923e875caf9118333b1a4aaafdc4"},
+    {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9ed0b1e5e0759d6b7f8e2f143894b2a7f3edd313f38cf44e1e15d360e11749b"},
+    {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:473e67837f786404570eae33c3b64a4b9635ae9f00145250851a1292f484c063"},
+    {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2fee3ed82a011184807d2127f1733b4f6b2ff6ec7151d83ef3477f3b96a13d03"},
+    {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d5fd67df77bab0d3f4ea1d7afca9ef15c2ee35dfb348c7b57ffb9782a6e4db6e"},
+    {file = "regex-2021.11.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5d408a642a5484b9b4d11dea15a489ea0928c7e410c7525cd892f4d04f2f617b"},
+    {file = "regex-2021.11.10-cp310-cp310-win32.whl", hash = "sha256:98ba568e8ae26beb726aeea2273053c717641933836568c2a0278a84987b2a1a"},
+    {file = "regex-2021.11.10-cp310-cp310-win_amd64.whl", hash = "sha256:780b48456a0f0ba4d390e8b5f7c661fdd218934388cde1a974010a965e200e12"},
+    {file = "regex-2021.11.10-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:dba70f30fd81f8ce6d32ddeef37d91c8948e5d5a4c63242d16a2b2df8143aafc"},
+    {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1f54b9b4b6c53369f40028d2dd07a8c374583417ee6ec0ea304e710a20f80a0"},
+    {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fbb9dc00e39f3e6c0ef48edee202f9520dafb233e8b51b06b8428cfcb92abd30"},
+    {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666abff54e474d28ff42756d94544cdfd42e2ee97065857413b72e8a2d6a6345"},
+    {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5537f71b6d646f7f5f340562ec4c77b6e1c915f8baae822ea0b7e46c1f09b733"},
+    {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2e07c6a26ed4bea91b897ee2b0835c21716d9a469a96c3e878dc5f8c55bb23"},
+    {file = "regex-2021.11.10-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca5f18a75e1256ce07494e245cdb146f5a9267d3c702ebf9b65c7f8bd843431e"},
+    {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:74cbeac0451f27d4f50e6e8a8f3a52ca074b5e2da9f7b505c4201a57a8ed6286"},
+    {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:3598893bde43091ee5ca0a6ad20f08a0435e93a69255eeb5f81b85e81e329264"},
+    {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:50a7ddf3d131dc5633dccdb51417e2d1910d25cbcf842115a3a5893509140a3a"},
+    {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:61600a7ca4bcf78a96a68a27c2ae9389763b5b94b63943d5158f2a377e09d29a"},
+    {file = "regex-2021.11.10-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:563d5f9354e15e048465061509403f68424fef37d5add3064038c2511c8f5e00"},
+    {file = "regex-2021.11.10-cp36-cp36m-win32.whl", hash = "sha256:93a5051fcf5fad72de73b96f07d30bc29665697fb8ecdfbc474f3452c78adcf4"},
+    {file = "regex-2021.11.10-cp36-cp36m-win_amd64.whl", hash = "sha256:b483c9d00a565633c87abd0aaf27eb5016de23fed952e054ecc19ce32f6a9e7e"},
+    {file = "regex-2021.11.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fff55f3ce50a3ff63ec8e2a8d3dd924f1941b250b0aac3d3d42b687eeff07a8e"},
+    {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32d2a2b02ccbef10145df9135751abea1f9f076e67a4e261b05f24b94219e36"},
+    {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53db2c6be8a2710b359bfd3d3aa17ba38f8aa72a82309a12ae99d3c0c3dcd74d"},
+    {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2207ae4f64ad3af399e2d30dde66f0b36ae5c3129b52885f1bffc2f05ec505c8"},
+    {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5ca078bb666c4a9d1287a379fe617a6dccd18c3e8a7e6c7e1eb8974330c626a"},
+    {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd33eb9bdcfbabab3459c9ee651d94c842bc8a05fabc95edf4ee0c15a072495e"},
+    {file = "regex-2021.11.10-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05b7d6d7e64efe309972adab77fc2af8907bb93217ec60aa9fe12a0dad35874f"},
+    {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:42b50fa6666b0d50c30a990527127334d6b96dd969011e843e726a64011485da"},
+    {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6e1d2cc79e8dae442b3fa4a26c5794428b98f81389af90623ffcc650ce9f6732"},
+    {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:0416f7399e918c4b0e074a0f66e5191077ee2ca32a0f99d4c187a62beb47aa05"},
+    {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ce298e3d0c65bd03fa65ffcc6db0e2b578e8f626d468db64fdf8457731052942"},
+    {file = "regex-2021.11.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dc07f021ee80510f3cd3af2cad5b6a3b3a10b057521d9e6aaeb621730d320c5a"},
+    {file = "regex-2021.11.10-cp37-cp37m-win32.whl", hash = "sha256:e71255ba42567d34a13c03968736c5d39bb4a97ce98188fafb27ce981115beec"},
+    {file = "regex-2021.11.10-cp37-cp37m-win_amd64.whl", hash = "sha256:07856afef5ffcc052e7eccf3213317fbb94e4a5cd8177a2caa69c980657b3cb4"},
+    {file = "regex-2021.11.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba05430e819e58544e840a68b03b28b6d328aff2e41579037e8bab7653b37d83"},
+    {file = "regex-2021.11.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f301b11b9d214f83ddaf689181051e7f48905568b0c7017c04c06dfd065e244"},
+    {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aaa4e0705ef2b73dd8e36eeb4c868f80f8393f5f4d855e94025ce7ad8525f50"},
+    {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:788aef3549f1924d5c38263104dae7395bf020a42776d5ec5ea2b0d3d85d6646"},
+    {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8af619e3be812a2059b212064ea7a640aff0568d972cd1b9e920837469eb3cb"},
+    {file = "regex-2021.11.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85bfa6a5413be0ee6c5c4a663668a2cad2cbecdee367630d097d7823041bdeec"},
+    {file = "regex-2021.11.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f23222527b307970e383433daec128d769ff778d9b29343fb3496472dc20dabe"},
+    {file = "regex-2021.11.10-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:da1a90c1ddb7531b1d5ff1e171b4ee61f6345119be7351104b67ff413843fe94"},
+    {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f5be7805e53dafe94d295399cfbe5227f39995a997f4fd8539bf3cbdc8f47ca8"},
+    {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a955b747d620a50408b7fdf948e04359d6e762ff8a85f5775d907ceced715129"},
+    {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:139a23d1f5d30db2cc6c7fd9c6d6497872a672db22c4ae1910be22d4f4b2068a"},
+    {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ca49e1ab99593438b204e00f3970e7a5f70d045267051dfa6b5f4304fcfa1dbf"},
+    {file = "regex-2021.11.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:96fc32c16ea6d60d3ca7f63397bff5c75c5a562f7db6dec7d412f7c4d2e78ec0"},
+    {file = "regex-2021.11.10-cp38-cp38-win32.whl", hash = "sha256:0617383e2fe465732af4509e61648b77cbe3aee68b6ac8c0b6fe934db90be5cc"},
+    {file = "regex-2021.11.10-cp38-cp38-win_amd64.whl", hash = "sha256:a3feefd5e95871872673b08636f96b61ebef62971eab044f5124fb4dea39919d"},
+    {file = "regex-2021.11.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7f325be2804246a75a4f45c72d4ce80d2443ab815063cdf70ee8fb2ca59ee1b"},
+    {file = "regex-2021.11.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:537ca6a3586931b16a85ac38c08cc48f10fc870a5b25e51794c74df843e9966d"},
+    {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef2afb0fd1747f33f1ee3e209bce1ed582d1896b240ccc5e2697e3275f037c7"},
+    {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:432bd15d40ed835a51617521d60d0125867f7b88acf653e4ed994a1f8e4995dc"},
+    {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b43c2b8a330a490daaef5a47ab114935002b13b3f9dc5da56d5322ff218eeadb"},
+    {file = "regex-2021.11.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:962b9a917dd7ceacbe5cd424556914cb0d636001e393b43dc886ba31d2a1e449"},
+    {file = "regex-2021.11.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa8c626d6441e2d04b6ee703ef2d1e17608ad44c7cb75258c09dd42bacdfc64b"},
+    {file = "regex-2021.11.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3c5fb32cc6077abad3bbf0323067636d93307c9fa93e072771cf9a64d1c0f3ef"},
+    {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cd410a1cbb2d297c67d8521759ab2ee3f1d66206d2e4328502a487589a2cb21b"},
+    {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e6096b0688e6e14af6a1b10eaad86b4ff17935c49aa774eac7c95a57a4e8c296"},
+    {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:529801a0d58809b60b3531ee804d3e3be4b412c94b5d267daa3de7fadef00f49"},
+    {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f594b96fe2e0821d026365f72ac7b4f0b487487fb3d4aaf10dd9d97d88a9737"},
+    {file = "regex-2021.11.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2409b5c9cef7054dde93a9803156b411b677affc84fca69e908b1cb2c540025d"},
+    {file = "regex-2021.11.10-cp39-cp39-win32.whl", hash = "sha256:3b5df18db1fccd66de15aa59c41e4f853b5df7550723d26aa6cb7f40e5d9da5a"},
+    {file = "regex-2021.11.10-cp39-cp39-win_amd64.whl", hash = "sha256:83ee89483672b11f8952b158640d0c0ff02dc43d9cb1b70c1564b49abe92ce29"},
+    {file = "regex-2021.11.10.tar.gz", hash = "sha256:f341ee2df0999bfdf7a95e448075effe0db212a59387de1a70690e4acb03d4c6"},
 ]
 requests = [
     {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"},
@@ -3170,12 +3305,12 @@ six = [
     {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
 ]
 smmap = [
-    {file = "smmap-4.0.0-py2.py3-none-any.whl", hash = "sha256:a9a7479e4c572e2e775c404dcd3080c8dc49f39918c2cf74913d30c4c478e3c2"},
-    {file = "smmap-4.0.0.tar.gz", hash = "sha256:7e65386bd122d45405ddf795637b7f7d2b532e7e401d46bbe3fb49b9986d5182"},
+    {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"},
+    {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"},
 ]
 snowballstemmer = [
-    {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"},
-    {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"},
+    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
 ]
 social-auth-app-django = [
     {file = "social-auth-app-django-4.0.0.tar.gz", hash = "sha256:2c69e57df0b30c9c1823519c5f1992cbe4f3f98fdc7d95c840e091a752708840"},
@@ -3191,16 +3326,16 @@ sqlparse = [
     {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"},
 ]
 stevedore = [
-    {file = "stevedore-3.4.0-py3-none-any.whl", hash = "sha256:920ce6259f0b2498aaa4545989536a27e4e4607b8318802d7ddc3a533d3d069e"},
-    {file = "stevedore-3.4.0.tar.gz", hash = "sha256:59b58edb7f57b11897f150475e7bc0c39c5381f0b8e3fa9f5c20ce6c89ec4aa1"},
+    {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"},
+    {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"},
 ]
 svgwrite = [
     {file = "svgwrite-1.4.1-py3-none-any.whl", hash = "sha256:4b21652a1d9c543a6bf4f9f2a54146b214519b7540ca60cb99968ad09ef631d0"},
     {file = "svgwrite-1.4.1.zip", hash = "sha256:e220a4bf189e7e214a55e8a11421d152b5b6fb1dd660c86a8b6b61fe8cc2ac48"},
 ]
 swagger-spec-validator = [
-    {file = "swagger-spec-validator-2.7.3.tar.gz", hash = "sha256:f4f23ee4dbd52bfcde90b1144dde22304add6260e9f29252e9fd7814c9b8fd16"},
-    {file = "swagger_spec_validator-2.7.3-py2.py3-none-any.whl", hash = "sha256:d1514ec7e3c058c701f27cc74f85ceb876d6418c9db57786b9c54085ed5e29eb"},
+    {file = "swagger-spec-validator-2.7.4.tar.gz", hash = "sha256:2aee5e1fc0503be9f8299378b10c92169572781573c6de3315e831fd0559ba73"},
+    {file = "swagger_spec_validator-2.7.4-py2.py3-none-any.whl", hash = "sha256:4e373a4db5262e7257fde17d84c5c0178327b8057985ab1be63f580bfa009855"},
 ]
 tenacity = [
     {file = "tenacity-8.0.1-py3-none-any.whl", hash = "sha256:f78f4ea81b0fabc06728c11dc2a8c01277bfc5181b321a4770471902e3eb844a"},
@@ -3218,41 +3353,34 @@ toml = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
 ]
+tomli = [
+    {file = "tomli-1.2.2-py3-none-any.whl", hash = "sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade"},
+    {file = "tomli-1.2.2.tar.gz", hash = "sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee"},
+]
 transitions = [
-    {file = "transitions-0.8.9-py2.py3-none-any.whl", hash = "sha256:6e03db07fb29bfdb2f560c9da834d995782a06e50dda26e103cfdd5bcb1c56b7"},
-    {file = "transitions-0.8.9.tar.gz", hash = "sha256:fc2ec6d6b6f986cd7e28e119eeb9ba1c9cc51ab4fbbdb7f2dedad01983fd2de0"},
+    {file = "transitions-0.8.10-py2.py3-none-any.whl", hash = "sha256:2e9de3c453fafe3a8afef2c2bdc47e30a7a73e32d88f793ad4c1b6246f0cc364"},
+    {file = "transitions-0.8.10.tar.gz", hash = "sha256:b0385975a842e885c1a55c719d2f90164471665794d39d51f9eb3f11e1d9c8ac"},
 ]
 typed-ast = [
-    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"},
-    {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"},
-    {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"},
-    {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"},
-    {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"},
-    {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"},
-    {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"},
-    {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"},
-    {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"},
-    {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"},
-    {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"},
-    {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"},
-    {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"},
-    {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"},
+    {file = "typed_ast-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b310a207ee9fde3f46ba327989e6cba4195bc0c8c70a158456e7b10233e6bed"},
+    {file = "typed_ast-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52ca2b2b524d770bed7a393371a38e91943f9160a190141e0df911586066ecda"},
+    {file = "typed_ast-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14fed8820114a389a2b7e91624db5f85f3f6682fda09fe0268a59aabd28fe5f5"},
+    {file = "typed_ast-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:65c81abbabda7d760df7304d843cc9dbe7ef5d485504ca59a46ae2d1731d2428"},
+    {file = "typed_ast-1.5.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:37ba2ab65a0028b1a4f2b61a8fe77f12d242731977d274a03d68ebb751271508"},
+    {file = "typed_ast-1.5.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:49af5b8f6f03ed1eb89ee06c1d7c2e7c8e743d720c3746a5857609a1abc94c94"},
+    {file = "typed_ast-1.5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e4374a76e61399a173137e7984a1d7e356038cf844f24fd8aea46c8029a2f712"},
+    {file = "typed_ast-1.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ea517c2bb11c5e4ba7a83a91482a2837041181d57d3ed0749a6c382a2b6b7086"},
+    {file = "typed_ast-1.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:51040bf45aacefa44fa67fb9ebcd1f2bec73182b99a532c2394eea7dabd18e24"},
+    {file = "typed_ast-1.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:806e0c7346b9b4af8c62d9a29053f484599921a4448c37fbbcbbf15c25138570"},
+    {file = "typed_ast-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a67fd5914603e2165e075f1b12f5a8356bfb9557e8bfb74511108cfbab0f51ed"},
+    {file = "typed_ast-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:224afecb8b39739f5c9562794a7c98325cb9d972712e1a98b6989a4720219541"},
+    {file = "typed_ast-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:155b74b078be842d2eb630dd30a280025eca0a5383c7d45853c27afee65f278f"},
+    {file = "typed_ast-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:361b9e5d27bd8e3ccb6ea6ad6c4f3c0be322a1a0f8177db6d56264fa0ae40410"},
+    {file = "typed_ast-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:618912cbc7e17b4aeba86ffe071698c6e2d292acbd6d1d5ec1ee724b8c4ae450"},
+    {file = "typed_ast-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7e6731044f748340ef68dcadb5172a4b1f40847a2983fe3983b2a66445fbc8e6"},
+    {file = "typed_ast-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e8a9b9c87801cecaad3b4c2b8876387115d1a14caa602c1618cedbb0cb2a14e6"},
+    {file = "typed_ast-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:ec184dfb5d3d11e82841dbb973e7092b75f306b625fad7b2e665b64c5d60ab3f"},
+    {file = "typed_ast-1.5.0.tar.gz", hash = "sha256:ff4ad88271aa7a55f19b6a161ed44e088c393846d954729549e3cde8257747bb"},
 ]
 typing-extensions = [
     {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"},
@@ -3260,12 +3388,12 @@ typing-extensions = [
     {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
 ]
 uritemplate = [
-    {file = "uritemplate-3.0.1-py2.py3-none-any.whl", hash = "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f"},
-    {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"},
+    {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"},
+    {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"},
 ]
 urllib3 = [
-    {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"},
-    {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"},
+    {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
+    {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"},
 ]
 vine = [
     {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"},
@@ -3280,7 +3408,57 @@ win32-setctime = [
     {file = "win32_setctime-1.0.3.tar.gz", hash = "sha256:4e88556c32fdf47f64165a2180ba4552f8bb32c1103a2fafd05723a0bd42bd4b"},
 ]
 wrapt = [
-    {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
+    {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"},
+    {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"},
+    {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"},
+    {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"},
+    {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"},
+    {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"},
+    {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"},
+    {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"},
+    {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"},
+    {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"},
+    {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"},
+    {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"},
+    {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"},
+    {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"},
+    {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"},
+    {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"},
+    {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"},
+    {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"},
+    {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"},
+    {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"},
+    {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"},
+    {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"},
+    {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"},
+    {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"},
+    {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"},
+    {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"},
+    {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"},
+    {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"},
+    {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"},
+    {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"},
+    {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"},
+    {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"},
+    {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"},
+    {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"},
+    {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"},
+    {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"},
+    {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"},
+    {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"},
+    {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"},
+    {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"},
+    {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"},
+    {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"},
+    {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"},
+    {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"},
+    {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"},
+    {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"},
+    {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"},
+    {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"},
+    {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"},
+    {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"},
+    {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"},
 ]
 yamllint = [
     {file = "yamllint-1.26.3.tar.gz", hash = "sha256:3934dcde484374596d6b52d8db412929a169f6d9e52e20f9ade5bf3523d9b96e"},
@@ -3289,6 +3467,6 @@ yamlordereddictloader = [
     {file = "yamlordereddictloader-0.4.0.tar.gz", hash = "sha256:7f30f0b99ea3f877f7cb340c570921fa9d639b7f69cba18be051e27f8de2080e"},
 ]
 zipp = [
-    {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"},
-    {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"},
+    {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"},
+    {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"},
 ]
diff --git a/pyproject.toml b/pyproject.toml
index c7246f2e..ab1f4e1f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "nautobot-golden-config"
-version = "0.9.9"
+version = "0.9.10"
 description = "A plugin for configuration on nautobot"
 authors = ["Network to Code, LLC", "<opensource@networktocode.com>"]
 
@@ -23,6 +23,7 @@ classifiers = [
     "Programming Language :: Python :: 3.6",
     "Programming Language :: Python :: 3.7",
     "Programming Language :: Python :: 3.8",
+    "Programming Language :: Python :: 3.9",
 ]
 packages = [
     { include = "nautobot_golden_config" },
@@ -30,22 +31,22 @@ packages = [
 
 [tool.poetry.dependencies]
 python = "^3.6"
-astroid = "^2.5.5"
 deepdiff = "^5.5.0"
-django-debug-toolbar = "^3.2.1"
 django-pivot = "^1.8.1"
 matplotlib = "^3.3.2"
-nautobot-plugin-nornir = ">=0.9.4"
+nautobot-plugin-nornir = ">=0.9.7"
 
 [tool.poetry.dev-dependencies]
-black = "^20.8b1"
-bandit = "^1.6.2"
-pylint = "2.7.4"
-pylint-django = "^2.0.15"
-pydocstyle = "^5.0.2"
-flake8 = "^3.8.4"
-invoke = "^1.5.0"
-yamllint = "^1.26.3"
+bandit = "*"
+black = {version="^21.10b0", python="^3.6.2"}
+django-debug-toolbar = "*"
+flake8 = "*"
+invoke = "*"
+pydocstyle = "*"
+pylint = "*"
+pylint-django = "*"
+yamllint = "*"
+Markdown = "3.3.4" # temp pin for https://github.com/Python-Markdown/markdown/issues/1195
 
 
 [tool.black]


Test patch:
diff --git a/nautobot_golden_config/tests/conftest.py b/nautobot_golden_config/tests/conftest.py
index 28622a54..a09c99d2 100644
--- a/nautobot_golden_config/tests/conftest.py
+++ b/nautobot_golden_config/tests/conftest.py
@@ -1,19 +1,146 @@
 """Params for testing."""
-from nautobot.dcim.models import Device, Site, Manufacturer, DeviceType, DeviceRole, Region, Platform
+from nautobot.dcim.models import Device, Site, Manufacturer, DeviceType, DeviceRole, Rack, RackGroup, Region, Platform
+from nautobot.tenancy.models import Tenant, TenantGroup
+from nautobot.extras.models import Status
+
 
 from nautobot_golden_config.models import ConfigCompliance, ComplianceFeature, ComplianceRule
 from nautobot_golden_config.choices import ComplianceRuleTypeChoice
 
 
+def create_device_data():
+    """Creates a Device and associated data."""
+    manufacturers = (
+        Manufacturer.objects.create(name="Manufacturer 1", slug="manufacturer-1"),
+        Manufacturer.objects.create(name="Manufacturer 2", slug="manufacturer-2"),
+        Manufacturer.objects.create(name="Manufacturer 3", slug="manufacturer-3"),
+    )
+
+    device_types = (
+        DeviceType.objects.create(
+            manufacturer=manufacturers[0],
+            model="Model 1",
+            slug="model-1",
+            is_full_depth=True,
+        ),
+        DeviceType.objects.create(
+            manufacturer=manufacturers[1],
+            model="Model 2",
+            slug="model-2",
+            is_full_depth=True,
+        ),
+        DeviceType.objects.create(
+            manufacturer=manufacturers[2],
+            model="Model 3",
+            slug="model-3",
+            is_full_depth=False,
+        ),
+    )
+
+    device_roles = (
+        DeviceRole.objects.create(name="Device Role 1", slug="device-role-1"),
+        DeviceRole.objects.create(name="Device Role 2", slug="device-role-2"),
+        DeviceRole.objects.create(name="Device Role 3", slug="device-role-3"),
+    )
+
+    device_statuses = Status.objects.get_for_model(Device)
+    device_status_map = {ds.slug: ds for ds in device_statuses.all()}
+
+    platforms = (
+        Platform.objects.create(name="Platform 1", slug="platform-1"),
+        Platform.objects.create(name="Platform 2", slug="platform-2"),
+        Platform.objects.create(name="Platform 3", slug="platform-3"),
+    )
+
+    regions = (
+        Region.objects.create(name="Region 1", slug="region-1"),
+        Region.objects.create(name="Region 2", slug="region-2"),
+        Region.objects.create(name="Region 3", slug="region-3"),
+    )
+
+    sites = (
+        Site.objects.create(name="Site 1", slug="site-1", region=regions[0]),
+        Site.objects.create(name="Site 2", slug="site-2", region=regions[1]),
+        Site.objects.create(name="Site 3", slug="site-3", region=regions[2]),
+    )
+
+    rack_groups = (
+        RackGroup.objects.create(name="Rack Group 1", slug="rack-group-1", site=sites[0]),
+        RackGroup.objects.create(name="Rack Group 2", slug="rack-group-2", site=sites[1]),
+        RackGroup.objects.create(name="Rack Group 3", slug="rack-group-3", site=sites[2]),
+    )
+
+    racks = (
+        Rack.objects.create(name="Rack 1", site=sites[0], group=rack_groups[0]),
+        Rack.objects.create(name="Rack 2", site=sites[1], group=rack_groups[1]),
+        Rack.objects.create(name="Rack 3", site=sites[2], group=rack_groups[2]),
+    )
+
+    tenant_groups = (
+        TenantGroup.objects.create(name="Tenant group 1", slug="tenant-group-1"),
+        TenantGroup.objects.create(name="Tenant group 2", slug="tenant-group-2"),
+        TenantGroup.objects.create(name="Tenant group 3", slug="tenant-group-3"),
+    )
+
+    tenants = (
+        Tenant.objects.create(name="Tenant 1", slug="tenant-1", group=tenant_groups[0]),
+        Tenant.objects.create(name="Tenant 2", slug="tenant-2", group=tenant_groups[1]),
+        Tenant.objects.create(name="Tenant 3", slug="tenant-3", group=tenant_groups[2]),
+    )
+
+    Device.objects.create(
+        name="Device 1",
+        device_type=device_types[0],
+        device_role=device_roles[0],
+        platform=platforms[0],
+        tenant=tenants[0],
+        site=sites[0],
+        rack=racks[0],
+        status=device_status_map["active"],
+    )
+    Device.objects.create(
+        name="Device 2",
+        device_type=device_types[1],
+        device_role=device_roles[1],
+        platform=platforms[1],
+        tenant=tenants[1],
+        site=sites[1],
+        rack=racks[1],
+        status=device_status_map["staged"],
+    )
+    Device.objects.create(
+        name="Device 3",
+        device_type=device_types[2],
+        device_role=device_roles[2],
+        platform=platforms[2],
+        tenant=tenants[2],
+        site=sites[2],
+        rack=racks[2],
+        status=device_status_map["failed"],
+    )
+    Device.objects.create(
+        name="Device 4",
+        device_type=device_types[0],
+        device_role=device_roles[0],
+        platform=platforms[0],
+        tenant=tenants[0],
+        site=sites[0],
+        rack=racks[0],
+        status=device_status_map["active"],
+    )
+
+
 def create_device(name="foobaz"):
     """Creates a Device to be used with tests."""
-    parent_region, _ = Region.objects.get_or_create(name="Parent Region", slug="parent_region")
-    child_region, _ = Region.objects.get_or_create(name="Child Region", slug="child_region", parent=parent_region)
-    site, _ = Site.objects.get_or_create(name="foo", slug="foo", region=child_region)
-    manufacturer, _ = Manufacturer.objects.get_or_create(name="bar")
-    device_role, _ = DeviceRole.objects.get_or_create(name="baz")
-    device_type, _ = DeviceType.objects.get_or_create(manufacturer=manufacturer)
-    platform, _ = Platform.objects.get_or_create(manufacturer=manufacturer)
+    parent_region, _ = Region.objects.get_or_create(name="Parent Region 1", slug="parent_region-1")
+    child_region, _ = Region.objects.get_or_create(name="Child Region 1", slug="child_region-1", parent=parent_region)
+    site, _ = Site.objects.get_or_create(name="Site 1", slug="site-1", region=child_region)
+    manufacturer, _ = Manufacturer.objects.get_or_create(name="Manufacturer 1", slug="manufacturer-1")
+    device_role, _ = DeviceRole.objects.get_or_create(name="Role 1", slug="role-1")
+    device_type, _ = DeviceType.objects.get_or_create(
+        manufacturer=manufacturer, model="Device Type 1", slug="device-type-1"
+    )
+    platform, _ = Platform.objects.get_or_create(manufacturer=manufacturer, name="Platform 1", slug="platform-1")
     device = Device.objects.create(
         name=name, platform=platform, site=site, device_role=device_role, device_type=device_type
     )
@@ -22,8 +149,7 @@ def create_device(name="foobaz"):
 
 def create_feature_rule_json(device, feature="foo", rule="json"):
     """Creates a Feature/Rule Mapping and Returns the rule."""
-    feature_obj = ComplianceFeature(slug=feature, name=feature)
-    feature_obj.save()
+    feature_obj, _ = ComplianceFeature.objects.get_or_create(slug=feature, name=feature)
     rule = ComplianceRule(
         feature=feature_obj,
         platform=device.platform,
diff --git a/nautobot_golden_config/tests/test_api.py b/nautobot_golden_config/tests/test_api.py
index ff744ec2..8f3e3270 100644
--- a/nautobot_golden_config/tests/test_api.py
+++ b/nautobot_golden_config/tests/test_api.py
@@ -25,7 +25,7 @@ def setUp(self):
     def test_root(self):
         """Validate the root for Nautobot Chatops API."""
         url = reverse("plugins-api:nautobot_golden_config-api:api-root")
-        response = self.client.get("{}?format=api".format(url), **self.header)
+        response = self.client.get(f"{url}?format=api", **self.header)
         self.assertEqual(response.status_code, 200)
 
     def test_device_list(self):
diff --git a/nautobot_golden_config/tests/test_filters.py b/nautobot_golden_config/tests/test_filters.py
new file mode 100644
index 00000000..32fd60ed
--- /dev/null
+++ b/nautobot_golden_config/tests/test_filters.py
@@ -0,0 +1,301 @@
+"""Unit tests for nautobot_golden_config models."""
+
+from unittest import skip
+from django.test import TestCase
+
+from nautobot.dcim.models import Device, Platform
+from nautobot_golden_config import filters, models
+
+from .conftest import create_feature_rule_json, create_device_data
+
+
+class ConfigComplianceModelTestCase(TestCase):
+    """Test filtering operations for ConfigCompliance Model."""
+
+    queryset = models.ConfigCompliance.objects.all()
+    filterset = filters.ConfigComplianceFilterSet
+
+    def setUp(self):
+        """Set up base objects."""
+        create_device_data()
+        self.dev01 = Device.objects.get(name="Device 1")
+        dev02 = Device.objects.get(name="Device 2")
+        dev03 = Device.objects.get(name="Device 3")
+        dev04 = Device.objects.get(name="Device 4")
+
+        feature_dev01 = create_feature_rule_json(self.dev01)
+        feature_dev02 = create_feature_rule_json(dev02)
+        feature_dev03 = create_feature_rule_json(dev03)
+
+        updates = [
+            {"device": self.dev01, "feature": feature_dev01},
+            {"device": dev02, "feature": feature_dev02},
+            {"device": dev03, "feature": feature_dev03},
+            {"device": dev04, "feature": feature_dev01},
+        ]
+        for update in updates:
+            models.ConfigCompliance.objects.create(
+                device=update["device"],
+                rule=update["feature"],
+                actual={"foo": {"bar-1": "baz"}},
+                intended={"foo": {"bar-1": "baz"}},
+            )
+
+    def test_id(self):
+        """Test filtering by ID (primary key)."""
+        params = {"id": self.queryset.values_list("pk", flat=True)[0]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_full(self):
+        """Test without filtering to ensure all devices have been added."""
+        self.assertEqual(self.queryset.count(), 4)
+
+    def test_device(self):
+        """Test filtering by Device."""
+        params = {"device": [self.dev01.name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+        params = {"device_id": [self.dev01.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_search(self):
+        """Test filtering by Q search value."""
+        params = {"q": self.dev01.name[-1:]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_region(self):
+        """Test filtering by Region."""
+        params = {"region": [self.dev01.site.region]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"region_id": [self.dev01.site.region.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_site(self):
+        """Test filtering by Site."""
+        params = {"site": [self.dev01.site.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"site_id": [self.dev01.site.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_tenant(self):
+        """Test filtering by Tenant."""
+        params = {"tenant": [self.dev01.tenant.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"tenant_id": [self.dev01.tenant.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_tenant_group(self):
+        """Test filtering by Tenant Group."""
+        params = {"tenant_group": [self.dev01.tenant.group.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"tenant_group_id": [self.dev01.tenant.group.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_rack(self):
+        """Test filtering by Rack."""
+        params = {"rack": [self.dev01.rack.name]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"rack_id": [self.dev01.rack.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_rack_group(self):
+        """Test filtering by Rack Group."""
+        params = {"rack_group": [self.dev01.rack.group.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"rack_group_id": [self.dev01.rack.group.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_role(self):
+        """Test filtering by Role."""
+        params = {"role": [self.dev01.device_role.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"role_id": [self.dev01.device_role.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_platform(self):
+        """Test filtering by Platform."""
+        params = {"platform": [self.dev01.platform.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"platform_id": [self.dev01.platform.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_manufacturer(self):
+        """Test filtering by Manufacturer."""
+        params = {"manufacturer": [self.dev01.device_type.manufacturer.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"manufacturer_id": [self.dev01.device_type.manufacturer.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    def test_device_type(self):
+        """Test filtering by Device Type."""
+        params = {"device_type": [self.dev01.device_type.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"device_type_id": [self.dev01.device_type.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+    @skip("Update Status filtering")
+    def test_device_status(self):
+        """Test filtering by Device Status."""
+        params = {"device_status": [self.dev01.status.slug]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"device_status_id": [self.dev01.status.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+
+class GoldenConfigModelTestCase(ConfigComplianceModelTestCase):
+    """Test filtering operations for GoldenConfig Model."""
+
+    queryset = models.GoldenConfig.objects.all()
+    filterset = filters.GoldenConfigFilterSet
+
+    def setUp(self):
+        """Set up base objects."""
+        create_device_data()
+        self.dev01 = Device.objects.get(name="Device 1")
+        dev02 = Device.objects.get(name="Device 2")
+        dev03 = Device.objects.get(name="Device 3")
+        dev04 = Device.objects.get(name="Device 4")
+
+        updates = [self.dev01, dev02, dev03, dev04]
+        for update in updates:
+            models.GoldenConfig.objects.create(
+                device=update,
+            )
+
+
+class ConfigRemoveModelTestCase(TestCase):
+    """Test filtering operations for ConfigRemove Model."""
+
+    queryset = models.ConfigRemove.objects.all()
+    filterset = filters.ConfigRemoveFilterSet
+
+    def setUp(self):
+        """Setup Object."""
+        self.platform1 = Platform.objects.create(name="Platform 1", slug="platform-1")
+        platform2 = Platform.objects.create(name="Platform 2", slug="platform-2")
+        self.obj1 = models.ConfigRemove.objects.create(
+            name="Remove 1", platform=self.platform1, description="Description 1", regex="^Remove 1"
+        )
+        models.ConfigRemove.objects.create(
+            name="Remove 2", platform=self.platform1, description="Description 2", regex="^Remove 2"
+        )
+        models.ConfigRemove.objects.create(
+            name="Remove 3", platform=platform2, description="Description 3", regex="^Remove 3"
+        )
+
+    def test_id(self):
+        """Test filtering by ID (primary key)."""
+        params = {"id": self.queryset.values_list("pk", flat=True)[0]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_full(self):
+        """Test without filtering to ensure all have been added."""
+        self.assertEqual(self.queryset.count(), 3)
+
+    def test_name(self):
+        """Test filtering by Name."""
+        params = {"name": self.obj1.name}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_search(self):
+        """Test filtering by Q search value."""
+        params = {"q": self.obj1.name[-1:]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_platform(self):
+        """Test filtering by Platform."""
+        params = {"platform": [self.platform1]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+        params = {"platform_id": [self.platform1.id]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
+
+class ConfigReplaceModelTestCase(ConfigRemoveModelTestCase):
+    """Test filtering operations for ConfigReplace Model."""
+
+    queryset = models.ConfigReplace.objects.all()
+    filterset = filters.ConfigReplaceFilterSet
+
+    def setUp(self):
+        """Setup Object."""
+        self.platform1 = Platform.objects.create(name="Platform 1", slug="platform-1")
+        platform2 = Platform.objects.create(name="Platform 2", slug="platform-2")
+        self.obj1 = models.ConfigReplace.objects.create(
+            name="Remove 1",
+            platform=self.platform1,
+            description="Description 1",
+            regex="^Remove 1",
+            replace="Replace 1",
+        )
+        models.ConfigReplace.objects.create(
+            name="Remove 2",
+            platform=self.platform1,
+            description="Description 2",
+            regex="^Remove 2",
+            replace="Replace 2",
+        )
+        models.ConfigReplace.objects.create(
+            name="Remove 3", platform=platform2, description="Description 3", regex="^Remove 3", replace="Replace 3"
+        )
+
+
+class ComplianceRuleModelTestCase(ConfigRemoveModelTestCase):
+    """Test filtering operations for ComplianceRule Model."""
+
+    queryset = models.ComplianceRule.objects.all()
+    filterset = filters.ComplianceRuleFilterSet
+
+    def setUp(self):
+        """Setup Object."""
+        self.platform1 = Platform.objects.create(name="Platform 1", slug="platform-1")
+        platform2 = Platform.objects.create(name="Platform 2", slug="platform-2")
+        feature1 = models.ComplianceFeature.objects.create(name="Feature 1", slug="feature-1")
+        feature2 = models.ComplianceFeature.objects.create(name="Feature 2", slug="feature-2")
+        self.obj1 = models.ComplianceRule.objects.create(
+            platform=self.platform1, feature=feature1, config_type="cli", config_ordered=True, match_config="config 1"
+        )
+        models.ComplianceRule.objects.create(
+            platform=self.platform1, feature=feature2, config_type="cli", config_ordered=True, match_config="config 2"
+        )
+        models.ComplianceRule.objects.create(
+            platform=platform2, feature=feature1, config_type="cli", config_ordered=True, match_config="config 3"
+        )
+
+    def test_name(self):
+        """Override since there is no name on this model, but keeping DRY."""
+
+    def test_search(self):
+        """Test filtering by Q search value."""
+        params = {"q": "2"}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+
+class ComplianceFeatureModelTestCase(TestCase):
+    """Test filtering operations for ComplianceFeature Model."""
+
+    queryset = models.ComplianceFeature.objects.all()
+    filterset = filters.ComplianceFeatureFilterSet
+
+    def setUp(self):
+        """Setup Object."""
+        self.obj1 = models.ComplianceFeature.objects.create(name="Feature 1", slug="feature-1")
+        models.ComplianceFeature.objects.create(name="Feature 2", slug="feature-2")
+        models.ComplianceFeature.objects.create(name="Feature 3", slug="feature-3")
+
+    def test_full(self):
+        """Test without filtering to ensure all have been added."""
+        self.assertEqual(self.queryset.count(), 3)
+
+    def test_id(self):
+        """Test filtering by ID (primary key)."""
+        params = {"id": self.queryset.values_list("pk", flat=True)[0]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_name(self):
+        """Test filtering by Name."""
+        params = {"name": self.obj1.name}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
+
+    def test_search(self):
+        """Test filtering by Q search value."""
+        params = {"q": self.obj1.name[-1:]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)