Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 9.2.0 |
Comparing to | |
See all releases |
Code changes from version 9.1.0 to 9.2.0
- icwp-wpsf.php +1 -1
- plugin-spec.php +6 -4
- readme.txt +27 -24
- resources/css/bootstrap4.css +31 -50
- resources/css/bootstrap4.min.css +3 -3
- resources/css/plugin.css +3 -0
- resources/js/bootstrap4.bundle.js +100 -110
- resources/js/bootstrap4.bundle.min.js +3 -3
- resources/js/bootstrap4.js +79 -89
- resources/js/bootstrap4.min.js +3 -3
- resources/js/global-plugin.js +26 -10
- resources/js/plugin.js +14 -12
- src/config/feature-autoupdates.php +3 -3
- src/config/feature-comments_filter.php +0 -1
- src/config/feature-hack_protect.php +4 -0
- src/config/feature-ips.php +35 -32
- src/config/feature-lockdown.php +21 -10
- src/config/feature-login_protect.php +2 -2
- src/config/feature-plugin.php +8 -4
- src/features/admin_access_restriction.php +37 -160
- src/features/audit_trail.php +0 -73
- src/features/autoupdates.php +0 -112
- src/features/base.php +106 -415
- src/features/base_wpsf.php +2 -64
- src/features/comments_filter.php +23 -59
- src/features/firewall.php +0 -48
- src/features/hack_protect.php +37 -352
- src/features/headers.php +0 -48
- src/features/insights.php +92 -90
- src/features/ips.php +0 -36
- src/features/license.php +0 -79
- src/features/lockdown.php +12 -90
- src/features/login_protect.php +2 -118
- src/features/plugin.php +9 -119
- src/features/traffic.php +0 -31
- src/features/user_management.php +11 -128
- src/lib/src/Controller/Controller.php +18 -55
- src/lib/src/Controller/Utilities/Upgrade.php +4 -4
- src/lib/src/Databases/AdminNotes/Handler.php +13 -7
- src/lib/src/Databases/AuditTrail/Handler.php +17 -11
- src/lib/src/Databases/Base/Handler.php +51 -52
- src/lib/src/Databases/ChangeTracking/Handler.php +13 -7
- src/lib/src/Databases/Events/Handler.php +16 -10
- src/lib/src/Databases/FileLocker/Handler.php +13 -7
- src/lib/src/Databases/GeoIp/Handler.php +14 -10
- src/lib/src/Databases/IPs/Handler.php +20 -25
- src/lib/src/Databases/Reports/Handler.php +14 -8
- src/lib/src/Databases/ScanQueue/Handler.php +13 -7
- src/lib/src/Databases/Scanner/Handler.php +13 -7
- src/lib/src/Databases/Session/Handler.php +14 -8
- src/lib/src/Databases/Tally/Handler.php +13 -7
- src/lib/src/Databases/Traffic/Handler.php +17 -11
- src/lib/src/Helpers/QuickAccess.php +19 -0
- src/lib/src/Modules/AuditTrail/AjaxHandler.php +4 -4
- src/lib/src/Modules/AuditTrail/Options.php +2 -0
- src/lib/src/Modules/AuditTrail/Strings.php +17 -19
- src/lib/src/Modules/AuditTrail/UI.php +80 -0
- src/lib/src/Modules/Autoupdates/Strings.php +8 -8
- src/lib/src/Modules/Autoupdates/UI.php +112 -0
- src/lib/src/Modules/Base/AdminNotices.php +63 -68
- src/lib/src/Modules/Base/AjaxHandlerBase.php +2 -4
- src/lib/src/Modules/Base/AjaxHandlerShield.php +9 -9
- src/lib/src/Modules/Base/BaseModCon.php +0 -224
- src/lib/src/Modules/Base/BaseProcessor.php +1 -5
- src/lib/src/Modules/Base/Options.php +3 -15
- src/lib/src/Modules/Base/ShieldUI.php +61 -0
- src/lib/src/Modules/Base/Strings.php +12 -12
- src/lib/src/Modules/Base/UI.php +364 -0
- src/lib/src/Modules/BaseShield/ShieldProcessor.php +2 -2
- src/lib/src/Modules/CommentsFilter/AdminNotices.php +6 -4
- src/lib/src/Modules/CommentsFilter/AjaxHandler.php +4 -4
- src/lib/src/Modules/CommentsFilter/Options.php +41 -0
- src/lib/src/Modules/CommentsFilter/Scan/Bot.php +4 -4
- src/lib/src/Modules/CommentsFilter/Scan/Scanner.php +20 -16
- src/lib/src/Modules/CommentsFilter/Strings.php +8 -8
- src/lib/src/Modules/CommentsFilter/UI.php +53 -0
- src/lib/src/Modules/Events/AjaxHandler.php +4 -4
- src/lib/src/Modules/Events/Options.php +1 -0
- src/lib/src/Modules/Firewall/Strings.php +8 -8
- src/lib/src/Modules/Firewall/UI.php +56 -0
- src/lib/src/Modules/HackGuard/AjaxHandler.php +5 -5
- src/lib/src/Modules/HackGuard/Lib/FileLocker/File.php +15 -15
- src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php +19 -7
- src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php +0 -2
- src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Delete.php +0 -2
- src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php +0 -2
- src/lib/src/Modules/HackGuard/Options.php +5 -2
- src/lib/src/Modules/HackGuard/Scan/Queue/CompleteQueue.php +11 -10
- src/lib/src/Modules/HackGuard/Scan/Queue/ConvertBetweenTypes.php +1 -1
- src/lib/src/Modules/HackGuard/Scan/Queue/QueueProcessor.php +0 -2
- src/lib/src/Modules/HackGuard/Strings.php +15 -14
- src/lib/src/Modules/HackGuard/UI.php +703 -0
- src/lib/src/Modules/Headers/Strings.php +8 -8
- src/lib/src/Modules/Headers/UI.php +56 -0
- src/lib/src/Modules/IPs/AjaxHandler.php +12 -12
- src/lib/src/Modules/IPs/BotTrack/TrackLinkCheese.php +11 -13
- src/lib/src/Modules/IPs/BotTrack/TrackLoginFailed.php +1 -1
- src/lib/src/Modules/IPs/Components/ProcessOffense.php +12 -14
- src/lib/src/Modules/IPs/Components/UnblockIpByMagicLink.php +37 -0
- src/lib/src/Modules/IPs/Lib/AutoUnblock.php +213 -0
- src/lib/src/Modules/IPs/Lib/BlacklistHandler.php +32 -26
- src/lib/src/Modules/IPs/Lib/BlockRequest.php +103 -77
- src/lib/src/Modules/IPs/Lib/Ops/DeleteIp.php +0 -21
- src/lib/src/Modules/IPs/Lib/{BlackmarkRequest.php → ProcessOffenses.php} +15 -14
- src/lib/src/Modules/IPs/Options.php +45 -19
- src/lib/src/Modules/IPs/Strings.php +31 -19
- src/lib/src/Modules/IPs/UI.php +43 -0
- src/lib/src/Modules/IPs/Upgrade.php +26 -0
- src/lib/src/Modules/License/AjaxHandler.php +4 -4
- src/lib/src/Modules/License/Lib/WpHashes/ApiTokenManager.php +0 -8
- src/lib/src/Modules/License/UI.php +96 -0
- src/lib/src/Modules/Lockdown/Lib/CleanRubbish.php +38 -0
- src/lib/src/Modules/Lockdown/Options.php +28 -0
- src/lib/src/Modules/Lockdown/Strings.php +19 -8
- src/lib/src/Modules/Lockdown/UI.php +97 -0
- src/lib/src/Modules/LoginGuard/AjaxHandler.php +4 -4
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php +17 -15
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/MemberPress.php +3 -4
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WPMembers.php +51 -0
- src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GaspJs.php +10 -10
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php +28 -25
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Profiles/CustomForms.php +67 -0
- src/lib/src/Modules/LoginGuard/Strings.php +14 -14
- src/lib/src/Modules/LoginGuard/UI.php +123 -0
- src/lib/src/Modules/Plugin/AdminNotices.php +8 -9
- src/lib/src/Modules/Plugin/AjaxHandler.php +4 -4
- src/lib/src/Modules/Plugin/Lib/ImportExport/Export.php +12 -12
- src/lib/src/Modules/Plugin/Lib/ImportExport/Import.php +5 -5
- src/lib/src/Modules/Plugin/Lib/Ops/ResetPlugin.php +5 -5
- src/lib/src/Modules/Plugin/Options.php +2 -0
- src/lib/src/Modules/Plugin/Strings.php +31 -21
- src/lib/src/Modules/Plugin/UI.php +122 -0
- src/lib/src/Modules/Reporting/Options.php +1 -0
- src/lib/src/Modules/Reporting/Strings.php +8 -8
- src/lib/src/Modules/SecurityAdmin/AdminNotices.php +1 -3
- src/lib/src/Modules/SecurityAdmin/AjaxHandler.php +4 -4
- src/lib/src/Modules/SecurityAdmin/Lib/Actions/RemoveSecAdmin.php +4 -4
- src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php +0 -2
- src/lib/src/Modules/SecurityAdmin/Options.php +10 -11
icwp-wpsf.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 9.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 9.2.0
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "9.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield",
|
@@ -111,7 +111,9 @@
|
|
111 |
"version_upgrades": [
|
112 |
"9.0.0",
|
113 |
"9.0.3",
|
114 |
-
"9.0.5"
|
|
|
|
|
115 |
],
|
116 |
"action_links": {
|
117 |
"remove": null,
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "9.2.0",
|
4 |
+
"release_timestamp": 1599122123,
|
5 |
+
"build": "202009.0301",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield",
|
111 |
"version_upgrades": [
|
112 |
"9.0.0",
|
113 |
"9.0.3",
|
114 |
+
"9.0.5",
|
115 |
+
"9.1.1",
|
116 |
+
"9.2.0"
|
117 |
],
|
118 |
"action_links": {
|
119 |
"remove": null,
|
readme.txt
CHANGED
@@ -7,8 +7,8 @@ Tags: scan, malware, firewall, two factor authentication, login protection
|
|
7 |
Requires at least: 3.5.2
|
8 |
Requires PHP: 5.4.0
|
9 |
Recommended PHP: 7.0
|
10 |
-
Tested up to: 5.
|
11 |
-
Stable tag: 9.
|
12 |
|
13 |
Smarter security protection from hackers through automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
|
14 |
|
@@ -216,7 +216,7 @@ protection for your site and you should choose which you need based on your own
|
|
216 |
Why do we do this? It's simple: performance and optimization - there is no reason to automatically turn on features for people that don't
|
217 |
need it as each site and set of requirements is different.
|
218 |
|
219 |
-
This plugin should install as any other WordPress.org
|
220 |
|
221 |
1. Browse to Plugins -> Add Plugin
|
222 |
1. Search: Shield
|
@@ -368,26 +368,29 @@ You'll also have access to our email technical support team.
|
|
368 |
|
369 |
You will always be able to use Shield Security and its free features in-full.
|
370 |
|
371 |
-
[Go Pro
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
##### [Please review the full Shield 9.
|
379 |
-
|
380 |
-
* **(.0) NEW**: [*PRO*]
|
381 |
-
* **(.0) NEW**:
|
382 |
-
* **(.0)
|
383 |
-
* **(.0)
|
384 |
-
* **(.0) IMPROVED**:
|
385 |
-
* **(.0) IMPROVED**:
|
386 |
-
* **(.0) IMPROVED**:
|
387 |
-
* **(.0) IMPROVED**:
|
388 |
-
* **(.0)
|
389 |
-
* **(.0)
|
390 |
-
* **(.0)
|
391 |
-
* **(.0)
|
|
|
|
|
|
|
392 |
|
393 |
##### [Entire Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
|
7 |
Requires at least: 3.5.2
|
8 |
Requires PHP: 5.4.0
|
9 |
Recommended PHP: 7.0
|
10 |
+
Tested up to: 5.4
|
11 |
+
Stable tag: 9.2.0
|
12 |
|
13 |
Smarter security protection from hackers through automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
|
14 |
|
216 |
Why do we do this? It's simple: performance and optimization - there is no reason to automatically turn on features for people that don't
|
217 |
need it as each site and set of requirements is different.
|
218 |
|
219 |
+
This plugin should install as any other WordPress.org repository plugin.
|
220 |
|
221 |
1. Browse to Plugins -> Add Plugin
|
222 |
1. Search: Shield
|
368 |
|
369 |
You will always be able to use Shield Security and its free features in-full.
|
370 |
|
371 |
+
[Go Pro from just $1/month](https://shsec.io/aa).
|
372 |
+
|
373 |
+
#### 9.2 Series
|
374 |
+
*Released: 2nd September 2020* - [Release Announcement](https://shsec.io/shieldrelease92)
|
375 |
+
|
376 |
+
**Important**: 9.2 is the *final* release to support PHP 5.x. Shield 10+ will require a minimum of PHP 7.0.
|
377 |
+
|
378 |
+
##### [Please review the full Shield 9.2 Upgrade Guide here](https://shsec.io/shieldupgradeguide92).
|
379 |
+
|
380 |
+
* **(.0) NEW**: [*PRO*] Allow logged-in users to automatically unblock their IP address.
|
381 |
+
* **(.0) NEW**: Add feature to allow Shield to automatically delete files such as `wp-config-sample.php`.
|
382 |
+
* **(.0) ADDED**: Provide native support for protection on WP Members plugin login/registration forms.
|
383 |
+
* **(.0) IMPROVED**: Automatic updates notification email is now only sent if on WordPress < 5.5.
|
384 |
+
* **(.0) IMPROVED**: Automatic updates notification email setting also applies to plugin/theme update emails.
|
385 |
+
* **(.0) IMPROVED**: Use WP Fastest Cache method to prevent caching of block pages. Whether it makes a difference is another thing.
|
386 |
+
* **(.0) IMPROVED**: Prevent spurious output from errors not relating to this plugin from affecting display of our admin pages.
|
387 |
+
* **(.0) IMPROVED**: `forceoff` file detection improved.
|
388 |
+
* **(.0) IMPROVED**: The File Locker is less likely to trigger an `open_basedir` warning.
|
389 |
+
* **(.0) IMPROVED**: Lots of code optimisation.
|
390 |
+
* **(.0) CHANGED**: Session cookie renamed from `icwp-wpsf` to `wp-icwp-wpsf` because some plugin devs feel a cookie is only important if it begins with `wp-`.
|
391 |
+
* **(.0) CHANGED**: Upgraded shipped Bootstrap libraries to latest available (v4.5.2).
|
392 |
+
* **(.0) FIXED**: Upgraded the database to support much larger values for the IP offenses counter.
|
393 |
+
* **(.0) FIXED**: MemberPress support had a bug where certain forms weren't checked for bots.
|
394 |
+
* **(.0) FIXED**: Cleaned some WP-CLI PHP notices on certain commands.
|
395 |
|
396 |
##### [Entire Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
|
resources/css/bootstrap4.css
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
/*!
|
2 |
-
* Bootstrap v4.5.
|
3 |
* Copyright 2011-2020 The Bootstrap Authors
|
4 |
* Copyright 2011-2020 Twitter, Inc.
|
5 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
6 |
*/
|
7 |
:root {
|
8 |
--blue: #007bff;
|
@@ -163,12 +163,12 @@ a:hover {
|
|
163 |
text-decoration: underline;
|
164 |
}
|
165 |
|
166 |
-
a:not([href]) {
|
167 |
color: inherit;
|
168 |
text-decoration: none;
|
169 |
}
|
170 |
|
171 |
-
a:not([href]):hover {
|
172 |
color: inherit;
|
173 |
text-decoration: none;
|
174 |
}
|
@@ -539,39 +539,12 @@ pre code {
|
|
539 |
overflow-y: scroll;
|
540 |
}
|
541 |
|
542 |
-
.container
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
}
|
549 |
-
|
550 |
-
@media (min-width: 576px) {
|
551 |
-
.container {
|
552 |
-
max-width: 540px;
|
553 |
-
}
|
554 |
-
}
|
555 |
-
|
556 |
-
@media (min-width: 768px) {
|
557 |
-
.container {
|
558 |
-
max-width: 720px;
|
559 |
-
}
|
560 |
-
}
|
561 |
-
|
562 |
-
@media (min-width: 992px) {
|
563 |
-
.container {
|
564 |
-
max-width: 960px;
|
565 |
-
}
|
566 |
-
}
|
567 |
-
|
568 |
-
@media (min-width: 1200px) {
|
569 |
-
.container {
|
570 |
-
max-width: 1140px;
|
571 |
-
}
|
572 |
-
}
|
573 |
-
|
574 |
-
.container-fluid, .container-sm, .container-md, .container-lg, .container-xl {
|
575 |
width: 100%;
|
576 |
padding-right: 15px;
|
577 |
padding-left: 15px;
|
@@ -640,7 +613,6 @@ pre code {
|
|
640 |
flex-basis: 0;
|
641 |
-ms-flex-positive: 1;
|
642 |
flex-grow: 1;
|
643 |
-
min-width: 0;
|
644 |
max-width: 100%;
|
645 |
}
|
646 |
|
@@ -884,7 +856,6 @@ pre code {
|
|
884 |
flex-basis: 0;
|
885 |
-ms-flex-positive: 1;
|
886 |
flex-grow: 1;
|
887 |
-
min-width: 0;
|
888 |
max-width: 100%;
|
889 |
}
|
890 |
.row-cols-sm-1 > * {
|
@@ -1087,7 +1058,6 @@ pre code {
|
|
1087 |
flex-basis: 0;
|
1088 |
-ms-flex-positive: 1;
|
1089 |
flex-grow: 1;
|
1090 |
-
min-width: 0;
|
1091 |
max-width: 100%;
|
1092 |
}
|
1093 |
.row-cols-md-1 > * {
|
@@ -1290,7 +1260,6 @@ pre code {
|
|
1290 |
flex-basis: 0;
|
1291 |
-ms-flex-positive: 1;
|
1292 |
flex-grow: 1;
|
1293 |
-
min-width: 0;
|
1294 |
max-width: 100%;
|
1295 |
}
|
1296 |
.row-cols-lg-1 > * {
|
@@ -1493,7 +1462,6 @@ pre code {
|
|
1493 |
flex-basis: 0;
|
1494 |
-ms-flex-positive: 1;
|
1495 |
flex-grow: 1;
|
1496 |
-
min-width: 0;
|
1497 |
max-width: 100%;
|
1498 |
}
|
1499 |
.row-cols-xl-1 > * {
|
@@ -2259,6 +2227,7 @@ textarea.form-control {
|
|
2259 |
.valid-tooltip {
|
2260 |
position: absolute;
|
2261 |
top: 100%;
|
|
|
2262 |
z-index: 5;
|
2263 |
display: none;
|
2264 |
max-width: 100%;
|
@@ -2359,6 +2328,7 @@ textarea.form-control {
|
|
2359 |
.invalid-tooltip {
|
2360 |
position: absolute;
|
2361 |
top: 100%;
|
|
|
2362 |
z-index: 5;
|
2363 |
display: none;
|
2364 |
max-width: 100%;
|
@@ -3776,6 +3746,7 @@ input[type="button"].btn-block {
|
|
3776 |
|
3777 |
.custom-control {
|
3778 |
position: relative;
|
|
|
3779 |
display: block;
|
3780 |
min-height: 1.5rem;
|
3781 |
padding-left: 1.5rem;
|
@@ -4312,12 +4283,14 @@ input[type="button"].btn-block {
|
|
4312 |
background-color: #007bff;
|
4313 |
}
|
4314 |
|
|
|
4315 |
.nav-fill .nav-item {
|
4316 |
-ms-flex: 1 1 auto;
|
4317 |
flex: 1 1 auto;
|
4318 |
text-align: center;
|
4319 |
}
|
4320 |
|
|
|
4321 |
.nav-justified .nav-item {
|
4322 |
-ms-flex-preferred-size: 0;
|
4323 |
flex-basis: 0;
|
@@ -4775,6 +4748,11 @@ input[type="button"].btn-block {
|
|
4775 |
border-bottom-left-radius: calc(0.25rem - 1px);
|
4776 |
}
|
4777 |
|
|
|
|
|
|
|
|
|
|
|
4778 |
.card-body {
|
4779 |
-ms-flex: 1 1 auto;
|
4780 |
flex: 1 1 auto;
|
@@ -4814,10 +4792,6 @@ input[type="button"].btn-block {
|
|
4814 |
border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
|
4815 |
}
|
4816 |
|
4817 |
-
.card-header + .list-group .list-group-item:first-child {
|
4818 |
-
border-top: 0;
|
4819 |
-
}
|
4820 |
-
|
4821 |
.card-footer {
|
4822 |
padding: 0.75rem 1.25rem;
|
4823 |
background-color: rgba(0, 0, 0, 0.03);
|
@@ -4847,6 +4821,7 @@ input[type="button"].btn-block {
|
|
4847 |
bottom: 0;
|
4848 |
left: 0;
|
4849 |
padding: 1.25rem;
|
|
|
4850 |
}
|
4851 |
|
4852 |
.card-img,
|
@@ -4958,6 +4933,10 @@ input[type="button"].btn-block {
|
|
4958 |
}
|
4959 |
}
|
4960 |
|
|
|
|
|
|
|
|
|
4961 |
.accordion > .card {
|
4962 |
overflow: hidden;
|
4963 |
}
|
@@ -5876,15 +5855,14 @@ a.close.disabled {
|
|
5876 |
}
|
5877 |
|
5878 |
.toast {
|
|
|
|
|
5879 |
max-width: 350px;
|
5880 |
-
overflow: hidden;
|
5881 |
font-size: 0.875rem;
|
5882 |
background-color: rgba(255, 255, 255, 0.85);
|
5883 |
background-clip: padding-box;
|
5884 |
border: 1px solid rgba(0, 0, 0, 0.1);
|
5885 |
box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);
|
5886 |
-
-webkit-backdrop-filter: blur(10px);
|
5887 |
-
backdrop-filter: blur(10px);
|
5888 |
opacity: 0;
|
5889 |
border-radius: 0.25rem;
|
5890 |
}
|
@@ -5916,6 +5894,8 @@ a.close.disabled {
|
|
5916 |
background-color: rgba(255, 255, 255, 0.85);
|
5917 |
background-clip: padding-box;
|
5918 |
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
|
|
|
5919 |
}
|
5920 |
|
5921 |
.toast-body {
|
@@ -10182,7 +10162,8 @@ a.text-dark:hover, a.text-dark:focus {
|
|
10182 |
}
|
10183 |
|
10184 |
.text-break {
|
10185 |
-
word-
|
|
|
10186 |
}
|
10187 |
|
10188 |
.text-reset {
|
1 |
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
* Copyright 2011-2020 The Bootstrap Authors
|
4 |
* Copyright 2011-2020 Twitter, Inc.
|
5 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
6 |
*/
|
7 |
:root {
|
8 |
--blue: #007bff;
|
163 |
text-decoration: underline;
|
164 |
}
|
165 |
|
166 |
+
a:not([href]):not([class]) {
|
167 |
color: inherit;
|
168 |
text-decoration: none;
|
169 |
}
|
170 |
|
171 |
+
a:not([href]):not([class]):hover {
|
172 |
color: inherit;
|
173 |
text-decoration: none;
|
174 |
}
|
539 |
overflow-y: scroll;
|
540 |
}
|
541 |
|
542 |
+
.container,
|
543 |
+
.container-fluid,
|
544 |
+
.container-sm,
|
545 |
+
.container-md,
|
546 |
+
.container-lg,
|
547 |
+
.container-xl {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
548 |
width: 100%;
|
549 |
padding-right: 15px;
|
550 |
padding-left: 15px;
|
613 |
flex-basis: 0;
|
614 |
-ms-flex-positive: 1;
|
615 |
flex-grow: 1;
|
|
|
616 |
max-width: 100%;
|
617 |
}
|
618 |
|
856 |
flex-basis: 0;
|
857 |
-ms-flex-positive: 1;
|
858 |
flex-grow: 1;
|
|
|
859 |
max-width: 100%;
|
860 |
}
|
861 |
.row-cols-sm-1 > * {
|
1058 |
flex-basis: 0;
|
1059 |
-ms-flex-positive: 1;
|
1060 |
flex-grow: 1;
|
|
|
1061 |
max-width: 100%;
|
1062 |
}
|
1063 |
.row-cols-md-1 > * {
|
1260 |
flex-basis: 0;
|
1261 |
-ms-flex-positive: 1;
|
1262 |
flex-grow: 1;
|
|
|
1263 |
max-width: 100%;
|
1264 |
}
|
1265 |
.row-cols-lg-1 > * {
|
1462 |
flex-basis: 0;
|
1463 |
-ms-flex-positive: 1;
|
1464 |
flex-grow: 1;
|
|
|
1465 |
max-width: 100%;
|
1466 |
}
|
1467 |
.row-cols-xl-1 > * {
|
2227 |
.valid-tooltip {
|
2228 |
position: absolute;
|
2229 |
top: 100%;
|
2230 |
+
left: 0;
|
2231 |
z-index: 5;
|
2232 |
display: none;
|
2233 |
max-width: 100%;
|
2328 |
.invalid-tooltip {
|
2329 |
position: absolute;
|
2330 |
top: 100%;
|
2331 |
+
left: 0;
|
2332 |
z-index: 5;
|
2333 |
display: none;
|
2334 |
max-width: 100%;
|
3746 |
|
3747 |
.custom-control {
|
3748 |
position: relative;
|
3749 |
+
z-index: 1;
|
3750 |
display: block;
|
3751 |
min-height: 1.5rem;
|
3752 |
padding-left: 1.5rem;
|
4283 |
background-color: #007bff;
|
4284 |
}
|
4285 |
|
4286 |
+
.nav-fill > .nav-link,
|
4287 |
.nav-fill .nav-item {
|
4288 |
-ms-flex: 1 1 auto;
|
4289 |
flex: 1 1 auto;
|
4290 |
text-align: center;
|
4291 |
}
|
4292 |
|
4293 |
+
.nav-justified > .nav-link,
|
4294 |
.nav-justified .nav-item {
|
4295 |
-ms-flex-preferred-size: 0;
|
4296 |
flex-basis: 0;
|
4748 |
border-bottom-left-radius: calc(0.25rem - 1px);
|
4749 |
}
|
4750 |
|
4751 |
+
.card > .card-header + .list-group,
|
4752 |
+
.card > .list-group + .card-footer {
|
4753 |
+
border-top: 0;
|
4754 |
+
}
|
4755 |
+
|
4756 |
.card-body {
|
4757 |
-ms-flex: 1 1 auto;
|
4758 |
flex: 1 1 auto;
|
4792 |
border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
|
4793 |
}
|
4794 |
|
|
|
|
|
|
|
|
|
4795 |
.card-footer {
|
4796 |
padding: 0.75rem 1.25rem;
|
4797 |
background-color: rgba(0, 0, 0, 0.03);
|
4821 |
bottom: 0;
|
4822 |
left: 0;
|
4823 |
padding: 1.25rem;
|
4824 |
+
border-radius: calc(0.25rem - 1px);
|
4825 |
}
|
4826 |
|
4827 |
.card-img,
|
4933 |
}
|
4934 |
}
|
4935 |
|
4936 |
+
.accordion {
|
4937 |
+
overflow-anchor: none;
|
4938 |
+
}
|
4939 |
+
|
4940 |
.accordion > .card {
|
4941 |
overflow: hidden;
|
4942 |
}
|
5855 |
}
|
5856 |
|
5857 |
.toast {
|
5858 |
+
-ms-flex-preferred-size: 350px;
|
5859 |
+
flex-basis: 350px;
|
5860 |
max-width: 350px;
|
|
|
5861 |
font-size: 0.875rem;
|
5862 |
background-color: rgba(255, 255, 255, 0.85);
|
5863 |
background-clip: padding-box;
|
5864 |
border: 1px solid rgba(0, 0, 0, 0.1);
|
5865 |
box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);
|
|
|
|
|
5866 |
opacity: 0;
|
5867 |
border-radius: 0.25rem;
|
5868 |
}
|
5894 |
background-color: rgba(255, 255, 255, 0.85);
|
5895 |
background-clip: padding-box;
|
5896 |
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
5897 |
+
border-top-left-radius: calc(0.25rem - 1px);
|
5898 |
+
border-top-right-radius: calc(0.25rem - 1px);
|
5899 |
}
|
5900 |
|
5901 |
.toast-body {
|
10162 |
}
|
10163 |
|
10164 |
.text-break {
|
10165 |
+
word-break: break-word !important;
|
10166 |
+
overflow-wrap: break-word !important;
|
10167 |
}
|
10168 |
|
10169 |
.text-reset {
|
resources/css/bootstrap4.min.css
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
/*!
|
2 |
-
* Bootstrap v4.5.
|
3 |
* Copyright 2011-2020 The Bootstrap Authors
|
4 |
* Copyright 2011-2020 Twitter, Inc.
|
5 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
6 |
-
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;min-width:0;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
|
7 |
/*# sourceMappingURL=bootstrap.min.css.map */
|
1 |
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
* Copyright 2011-2020 The Bootstrap Authors
|
4 |
* Copyright 2011-2020 Twitter, Inc.
|
5 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
6 |
+
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
|
7 |
/*# sourceMappingURL=bootstrap.min.css.map */
|
resources/css/plugin.css
CHANGED
@@ -1102,6 +1102,9 @@ input[type=checkbox].form-check-input {
|
|
1102 |
.content-options .option-description {
|
1103 |
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
1104 |
}
|
|
|
|
|
|
|
1105 |
.content-options .option_label_name {
|
1106 |
position: relative;
|
1107 |
/*display: block;*/
|
1102 |
.content-options .option-description {
|
1103 |
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
1104 |
}
|
1105 |
+
.content-options .option-description p {
|
1106 |
+
margin-bottom: 5px;
|
1107 |
+
}
|
1108 |
.content-options .option_label_name {
|
1109 |
position: relative;
|
1110 |
/*display: block;*/
|
resources/js/bootstrap4.bundle.js
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
/*!
|
2 |
-
* Bootstrap v4.5.
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
5 |
*/
|
6 |
(function (global, factory) {
|
7 |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery')) :
|
8 |
typeof define === 'function' && define.amd ? define(['exports', 'jquery'], factory) :
|
9 |
-
(global = global || self, factory(global.bootstrap = {}, global.jQuery));
|
10 |
}(this, (function (exports, $) { 'use strict';
|
11 |
|
12 |
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
|
@@ -27,53 +27,22 @@
|
|
27 |
return Constructor;
|
28 |
}
|
29 |
|
30 |
-
function
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
enumerable: true,
|
35 |
-
configurable: true,
|
36 |
-
writable: true
|
37 |
-
});
|
38 |
-
} else {
|
39 |
-
obj[key] = value;
|
40 |
-
}
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
if (Object.getOwnPropertySymbols) {
|
49 |
-
var symbols = Object.getOwnPropertySymbols(object);
|
50 |
-
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
51 |
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
52 |
-
});
|
53 |
-
keys.push.apply(keys, symbols);
|
54 |
-
}
|
55 |
-
|
56 |
-
return keys;
|
57 |
-
}
|
58 |
-
|
59 |
-
function _objectSpread2(target) {
|
60 |
-
for (var i = 1; i < arguments.length; i++) {
|
61 |
-
var source = arguments[i] != null ? arguments[i] : {};
|
62 |
-
|
63 |
-
if (i % 2) {
|
64 |
-
ownKeys(Object(source), true).forEach(function (key) {
|
65 |
-
_defineProperty(target, key, source[key]);
|
66 |
-
});
|
67 |
-
} else if (Object.getOwnPropertyDescriptors) {
|
68 |
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
69 |
-
} else {
|
70 |
-
ownKeys(Object(source)).forEach(function (key) {
|
71 |
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
72 |
-
});
|
73 |
}
|
74 |
-
}
|
75 |
|
76 |
-
|
|
|
|
|
|
|
77 |
}
|
78 |
|
79 |
function _inheritsLoose(subClass, superClass) {
|
@@ -84,8 +53,8 @@
|
|
84 |
|
85 |
/**
|
86 |
* --------------------------------------------------------------------------
|
87 |
-
* Bootstrap (v4.5.
|
88 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
89 |
* --------------------------------------------------------------------------
|
90 |
*/
|
91 |
/**
|
@@ -265,7 +234,7 @@
|
|
265 |
*/
|
266 |
|
267 |
var NAME = 'alert';
|
268 |
-
var VERSION = '4.5.
|
269 |
var DATA_KEY = 'bs.alert';
|
270 |
var EVENT_KEY = "." + DATA_KEY;
|
271 |
var DATA_API_KEY = '.data-api';
|
@@ -421,7 +390,7 @@
|
|
421 |
*/
|
422 |
|
423 |
var NAME$1 = 'button';
|
424 |
-
var VERSION$1 = '4.5.
|
425 |
var DATA_KEY$1 = 'bs.button';
|
426 |
var EVENT_KEY$1 = "." + DATA_KEY$1;
|
427 |
var DATA_API_KEY$1 = '.data-api';
|
@@ -556,11 +525,9 @@
|
|
556 |
return;
|
557 |
}
|
558 |
|
559 |
-
if (initialButton.tagName
|
560 |
-
|
561 |
}
|
562 |
-
|
563 |
-
Button._jQueryInterface.call($(button), 'toggle');
|
564 |
}
|
565 |
}).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
|
566 |
var button = $(event.target).closest(SELECTOR_BUTTON)[0];
|
@@ -616,7 +583,7 @@
|
|
616 |
*/
|
617 |
|
618 |
var NAME$2 = 'carousel';
|
619 |
-
var VERSION$2 = '4.5.
|
620 |
var DATA_KEY$2 = 'bs.carousel';
|
621 |
var EVENT_KEY$2 = "." + DATA_KEY$2;
|
622 |
var DATA_API_KEY$2 = '.data-api';
|
@@ -803,7 +770,7 @@
|
|
803 |
;
|
804 |
|
805 |
_proto._getConfig = function _getConfig(config) {
|
806 |
-
config =
|
807 |
Util.typeCheckConfig(NAME$2, config, DefaultType);
|
808 |
return config;
|
809 |
};
|
@@ -1093,10 +1060,10 @@
|
|
1093 |
return this.each(function () {
|
1094 |
var data = $(this).data(DATA_KEY$2);
|
1095 |
|
1096 |
-
var _config =
|
1097 |
|
1098 |
if (typeof config === 'object') {
|
1099 |
-
_config =
|
1100 |
}
|
1101 |
|
1102 |
var action = typeof config === 'string' ? config : _config.slide;
|
@@ -1134,7 +1101,7 @@
|
|
1134 |
return;
|
1135 |
}
|
1136 |
|
1137 |
-
var config =
|
1138 |
|
1139 |
var slideIndex = this.getAttribute('data-slide-to');
|
1140 |
|
@@ -1203,7 +1170,7 @@
|
|
1203 |
*/
|
1204 |
|
1205 |
var NAME$3 = 'collapse';
|
1206 |
-
var VERSION$3 = '4.5.
|
1207 |
var DATA_KEY$3 = 'bs.collapse';
|
1208 |
var EVENT_KEY$3 = "." + DATA_KEY$3;
|
1209 |
var DATA_API_KEY$3 = '.data-api';
|
@@ -1418,7 +1385,7 @@
|
|
1418 |
;
|
1419 |
|
1420 |
_proto._getConfig = function _getConfig(config) {
|
1421 |
-
config =
|
1422 |
config.toggle = Boolean(config.toggle); // Coerce string values
|
1423 |
|
1424 |
Util.typeCheckConfig(NAME$3, config, DefaultType$1);
|
@@ -1472,7 +1439,7 @@
|
|
1472 |
var $this = $(this);
|
1473 |
var data = $this.data(DATA_KEY$3);
|
1474 |
|
1475 |
-
var _config =
|
1476 |
|
1477 |
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
|
1478 |
_config.toggle = false;
|
@@ -1547,7 +1514,7 @@
|
|
1547 |
|
1548 |
/**!
|
1549 |
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
1550 |
-
* @version 1.16.
|
1551 |
* @license
|
1552 |
* Copyright (c) 2016 Federico Zivolo and contributors
|
1553 |
*
|
@@ -1893,7 +1860,7 @@
|
|
1893 |
var sideA = axis === 'x' ? 'Left' : 'Top';
|
1894 |
var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
|
1895 |
|
1896 |
-
return parseFloat(styles['border' + sideA + 'Width']
|
1897 |
}
|
1898 |
|
1899 |
function getSize(axis, body, html, computedStyle) {
|
@@ -1954,7 +1921,7 @@
|
|
1954 |
return obj;
|
1955 |
};
|
1956 |
|
1957 |
-
var _extends = Object.assign || function (target) {
|
1958 |
for (var i = 1; i < arguments.length; i++) {
|
1959 |
var source = arguments[i];
|
1960 |
|
@@ -1976,7 +1943,7 @@
|
|
1976 |
* @returns {Object} ClientRect like output
|
1977 |
*/
|
1978 |
function getClientRect(offsets) {
|
1979 |
-
return _extends({}, offsets, {
|
1980 |
right: offsets.left + offsets.width,
|
1981 |
bottom: offsets.top + offsets.height
|
1982 |
});
|
@@ -2048,8 +2015,8 @@
|
|
2048 |
var scrollParent = getScrollParent(children);
|
2049 |
|
2050 |
var styles = getStyleComputedProperty(parent);
|
2051 |
-
var borderTopWidth = parseFloat(styles.borderTopWidth
|
2052 |
-
var borderLeftWidth = parseFloat(styles.borderLeftWidth
|
2053 |
|
2054 |
// In cases where the parent is fixed, we must ignore negative scroll in offset calc
|
2055 |
if (fixedPosition && isHTML) {
|
@@ -2070,8 +2037,8 @@
|
|
2070 |
// differently when margins are applied to it. The margins are included in
|
2071 |
// the box of the documentElement, in the other cases not.
|
2072 |
if (!isIE10 && isHTML) {
|
2073 |
-
var marginTop = parseFloat(styles.marginTop
|
2074 |
-
var marginLeft = parseFloat(styles.marginLeft
|
2075 |
|
2076 |
offsets.top -= borderTopWidth - marginTop;
|
2077 |
offsets.bottom -= borderTopWidth - marginTop;
|
@@ -2264,7 +2231,7 @@
|
|
2264 |
};
|
2265 |
|
2266 |
var sortedAreas = Object.keys(rects).map(function (key) {
|
2267 |
-
return _extends({
|
2268 |
key: key
|
2269 |
}, rects[key], {
|
2270 |
area: getArea(rects[key])
|
@@ -2906,9 +2873,9 @@
|
|
2906 |
};
|
2907 |
|
2908 |
// Update `data` attributes, styles and arrowStyles
|
2909 |
-
data.attributes = _extends({}, attributes, data.attributes);
|
2910 |
-
data.styles = _extends({}, styles, data.styles);
|
2911 |
-
data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);
|
2912 |
|
2913 |
return data;
|
2914 |
}
|
@@ -3010,8 +2977,8 @@
|
|
3010 |
// Compute the sideValue using the updated popper offsets
|
3011 |
// take popper margin in account because we don't have this info available
|
3012 |
var css = getStyleComputedProperty(data.instance.popper);
|
3013 |
-
var popperMarginSide = parseFloat(css['margin' + sideCapitalized]
|
3014 |
-
var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']
|
3015 |
var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
|
3016 |
|
3017 |
// prevent arrowElement from being placed not contiguously to its popper
|
@@ -3188,7 +3155,7 @@
|
|
3188 |
|
3189 |
// this object contains `position`, we want to preserve it along with
|
3190 |
// any additional property we may add in the future
|
3191 |
-
data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
|
3192 |
|
3193 |
data = runModifiers(data.instance.modifiers, data, 'flip');
|
3194 |
}
|
@@ -3462,7 +3429,7 @@
|
|
3462 |
|
3463 |
order.forEach(function (placement) {
|
3464 |
var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
|
3465 |
-
popper = _extends({}, popper, check[side](placement));
|
3466 |
});
|
3467 |
|
3468 |
data.offsets.popper = popper;
|
@@ -3497,7 +3464,7 @@
|
|
3497 |
end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
|
3498 |
};
|
3499 |
|
3500 |
-
data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
|
3501 |
}
|
3502 |
|
3503 |
return data;
|
@@ -4029,7 +3996,7 @@
|
|
4029 |
this.update = debounce(this.update.bind(this));
|
4030 |
|
4031 |
// with {} we create a new object with the options inside it
|
4032 |
-
this.options = _extends({}, Popper.Defaults, options);
|
4033 |
|
4034 |
// init state
|
4035 |
this.state = {
|
@@ -4044,13 +4011,13 @@
|
|
4044 |
|
4045 |
// Deep merge modifiers options
|
4046 |
this.options.modifiers = {};
|
4047 |
-
Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
|
4048 |
-
_this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
|
4049 |
});
|
4050 |
|
4051 |
// Refactoring modifiers' list (Object => Array)
|
4052 |
this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
|
4053 |
-
return _extends({
|
4054 |
name: name
|
4055 |
}, _this.options.modifiers[name]);
|
4056 |
})
|
@@ -4166,7 +4133,7 @@
|
|
4166 |
*/
|
4167 |
|
4168 |
var NAME$4 = 'dropdown';
|
4169 |
-
var VERSION$4 = '4.5.
|
4170 |
var DATA_KEY$4 = 'bs.dropdown';
|
4171 |
var EVENT_KEY$4 = "." + DATA_KEY$4;
|
4172 |
var DATA_API_KEY$4 = '.data-api';
|
@@ -4393,7 +4360,7 @@
|
|
4393 |
};
|
4394 |
|
4395 |
_proto._getConfig = function _getConfig(config) {
|
4396 |
-
config =
|
4397 |
Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
|
4398 |
return config;
|
4399 |
};
|
@@ -4438,7 +4405,7 @@
|
|
4438 |
|
4439 |
if (typeof this._config.offset === 'function') {
|
4440 |
offset.fn = function (data) {
|
4441 |
-
data.offsets =
|
4442 |
return data;
|
4443 |
};
|
4444 |
} else {
|
@@ -4468,7 +4435,7 @@
|
|
4468 |
};
|
4469 |
}
|
4470 |
|
4471 |
-
return
|
4472 |
} // Static
|
4473 |
;
|
4474 |
|
@@ -4680,7 +4647,7 @@
|
|
4680 |
*/
|
4681 |
|
4682 |
var NAME$5 = 'modal';
|
4683 |
-
var VERSION$5 = '4.5.
|
4684 |
var DATA_KEY$5 = 'bs.modal';
|
4685 |
var EVENT_KEY$5 = "." + DATA_KEY$5;
|
4686 |
var DATA_API_KEY$5 = '.data-api';
|
@@ -4872,7 +4839,7 @@
|
|
4872 |
;
|
4873 |
|
4874 |
_proto._getConfig = function _getConfig(config) {
|
4875 |
-
config =
|
4876 |
Util.typeCheckConfig(NAME$5, config, DefaultType$3);
|
4877 |
return config;
|
4878 |
};
|
@@ -4888,11 +4855,24 @@
|
|
4888 |
return;
|
4889 |
}
|
4890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
4891 |
this._element.classList.add(CLASS_NAME_STATIC);
|
4892 |
|
4893 |
-
var modalTransitionDuration = Util.getTransitionDurationFromElement(this.
|
|
|
4894 |
$(this._element).one(Util.TRANSITION_END, function () {
|
4895 |
_this3._element.classList.remove(CLASS_NAME_STATIC);
|
|
|
|
|
|
|
|
|
|
|
|
|
4896 |
}).emulateTransitionEnd(modalTransitionDuration);
|
4897 |
|
4898 |
this._element.focus();
|
@@ -4918,6 +4898,8 @@
|
|
4918 |
|
4919 |
this._element.setAttribute('aria-modal', true);
|
4920 |
|
|
|
|
|
4921 |
if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
|
4922 |
modalBody.scrollTop = 0;
|
4923 |
} else {
|
@@ -5005,6 +4987,8 @@
|
|
5005 |
|
5006 |
this._element.removeAttribute('aria-modal');
|
5007 |
|
|
|
|
|
5008 |
this._isTransitioning = false;
|
5009 |
|
5010 |
this._showBackdrop(function () {
|
@@ -5186,7 +5170,7 @@
|
|
5186 |
return this.each(function () {
|
5187 |
var data = $(this).data(DATA_KEY$5);
|
5188 |
|
5189 |
-
var _config =
|
5190 |
|
5191 |
if (!data) {
|
5192 |
data = new Modal(this, _config);
|
@@ -5236,7 +5220,7 @@
|
|
5236 |
target = document.querySelector(selector);
|
5237 |
}
|
5238 |
|
5239 |
-
var config = $(target).data(DATA_KEY$5) ? 'toggle' :
|
5240 |
|
5241 |
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
5242 |
event.preventDefault();
|
@@ -5273,8 +5257,8 @@
|
|
5273 |
|
5274 |
/**
|
5275 |
* --------------------------------------------------------------------------
|
5276 |
-
* Bootstrap (v4.5.
|
5277 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
5278 |
* --------------------------------------------------------------------------
|
5279 |
*/
|
5280 |
var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
|
@@ -5399,7 +5383,7 @@
|
|
5399 |
*/
|
5400 |
|
5401 |
var NAME$6 = 'tooltip';
|
5402 |
-
var VERSION$6 = '4.5.
|
5403 |
var DATA_KEY$6 = 'bs.tooltip';
|
5404 |
var EVENT_KEY$6 = "." + DATA_KEY$6;
|
5405 |
var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
|
@@ -5787,7 +5771,7 @@
|
|
5787 |
return _this3._handlePopperPlacementChange(data);
|
5788 |
}
|
5789 |
};
|
5790 |
-
return
|
5791 |
};
|
5792 |
|
5793 |
_proto._getOffset = function _getOffset() {
|
@@ -5797,7 +5781,7 @@
|
|
5797 |
|
5798 |
if (typeof this.config.offset === 'function') {
|
5799 |
offset.fn = function (data) {
|
5800 |
-
data.offsets =
|
5801 |
return data;
|
5802 |
};
|
5803 |
} else {
|
@@ -5852,7 +5836,7 @@
|
|
5852 |
$(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
|
5853 |
|
5854 |
if (this.config.selector) {
|
5855 |
-
this.config =
|
5856 |
trigger: 'manual',
|
5857 |
selector: ''
|
5858 |
});
|
@@ -5952,7 +5936,7 @@
|
|
5952 |
delete dataAttributes[dataAttr];
|
5953 |
}
|
5954 |
});
|
5955 |
-
config =
|
5956 |
|
5957 |
if (typeof config.delay === 'number') {
|
5958 |
config.delay = {
|
@@ -6111,21 +6095,21 @@
|
|
6111 |
*/
|
6112 |
|
6113 |
var NAME$7 = 'popover';
|
6114 |
-
var VERSION$7 = '4.5.
|
6115 |
var DATA_KEY$7 = 'bs.popover';
|
6116 |
var EVENT_KEY$7 = "." + DATA_KEY$7;
|
6117 |
var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
|
6118 |
var CLASS_PREFIX$1 = 'bs-popover';
|
6119 |
var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
|
6120 |
|
6121 |
-
var Default$5 =
|
6122 |
placement: 'right',
|
6123 |
trigger: 'click',
|
6124 |
content: '',
|
6125 |
template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
|
6126 |
});
|
6127 |
|
6128 |
-
var DefaultType$5 =
|
6129 |
content: '(string|element|function)'
|
6130 |
});
|
6131 |
|
@@ -6291,7 +6275,7 @@
|
|
6291 |
*/
|
6292 |
|
6293 |
var NAME$8 = 'scrollspy';
|
6294 |
-
var VERSION$8 = '4.5.
|
6295 |
var DATA_KEY$8 = 'bs.scrollspy';
|
6296 |
var EVENT_KEY$8 = "." + DATA_KEY$8;
|
6297 |
var DATA_API_KEY$6 = '.data-api';
|
@@ -6405,7 +6389,7 @@
|
|
6405 |
;
|
6406 |
|
6407 |
_proto._getConfig = function _getConfig(config) {
|
6408 |
-
config =
|
6409 |
|
6410 |
if (typeof config.target !== 'string' && Util.isElement(config.target)) {
|
6411 |
var id = $(config.target).attr('id');
|
@@ -6583,7 +6567,7 @@
|
|
6583 |
*/
|
6584 |
|
6585 |
var NAME$9 = 'tab';
|
6586 |
-
var VERSION$9 = '4.5.
|
6587 |
var DATA_KEY$9 = 'bs.tab';
|
6588 |
var EVENT_KEY$9 = "." + DATA_KEY$9;
|
6589 |
var DATA_API_KEY$7 = '.data-api';
|
@@ -6809,7 +6793,7 @@
|
|
6809 |
*/
|
6810 |
|
6811 |
var NAME$a = 'toast';
|
6812 |
-
var VERSION$a = '4.5.
|
6813 |
var DATA_KEY$a = 'bs.toast';
|
6814 |
var EVENT_KEY$a = "." + DATA_KEY$a;
|
6815 |
var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
|
@@ -6862,6 +6846,8 @@
|
|
6862 |
return;
|
6863 |
}
|
6864 |
|
|
|
|
|
6865 |
if (this._config.animation) {
|
6866 |
this._element.classList.add(CLASS_NAME_FADE$5);
|
6867 |
}
|
@@ -6910,8 +6896,7 @@
|
|
6910 |
};
|
6911 |
|
6912 |
_proto.dispose = function dispose() {
|
6913 |
-
|
6914 |
-
this._timeout = null;
|
6915 |
|
6916 |
if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
|
6917 |
this._element.classList.remove(CLASS_NAME_SHOW$7);
|
@@ -6925,7 +6910,7 @@
|
|
6925 |
;
|
6926 |
|
6927 |
_proto._getConfig = function _getConfig(config) {
|
6928 |
-
config =
|
6929 |
Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
|
6930 |
return config;
|
6931 |
};
|
@@ -6955,6 +6940,11 @@
|
|
6955 |
} else {
|
6956 |
complete();
|
6957 |
}
|
|
|
|
|
|
|
|
|
|
|
6958 |
} // Static
|
6959 |
;
|
6960 |
|
1 |
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5 |
*/
|
6 |
(function (global, factory) {
|
7 |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery')) :
|
8 |
typeof define === 'function' && define.amd ? define(['exports', 'jquery'], factory) :
|
9 |
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bootstrap = {}, global.jQuery));
|
10 |
}(this, (function (exports, $) { 'use strict';
|
11 |
|
12 |
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
|
27 |
return Constructor;
|
28 |
}
|
29 |
|
30 |
+
function _extends() {
|
31 |
+
_extends = Object.assign || function (target) {
|
32 |
+
for (var i = 1; i < arguments.length; i++) {
|
33 |
+
var source = arguments[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
+
for (var key in source) {
|
36 |
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
37 |
+
target[key] = source[key];
|
38 |
+
}
|
39 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
|
|
41 |
|
42 |
+
return target;
|
43 |
+
};
|
44 |
+
|
45 |
+
return _extends.apply(this, arguments);
|
46 |
}
|
47 |
|
48 |
function _inheritsLoose(subClass, superClass) {
|
53 |
|
54 |
/**
|
55 |
* --------------------------------------------------------------------------
|
56 |
+
* Bootstrap (v4.5.2): util.js
|
57 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
58 |
* --------------------------------------------------------------------------
|
59 |
*/
|
60 |
/**
|
234 |
*/
|
235 |
|
236 |
var NAME = 'alert';
|
237 |
+
var VERSION = '4.5.2';
|
238 |
var DATA_KEY = 'bs.alert';
|
239 |
var EVENT_KEY = "." + DATA_KEY;
|
240 |
var DATA_API_KEY = '.data-api';
|
390 |
*/
|
391 |
|
392 |
var NAME$1 = 'button';
|
393 |
+
var VERSION$1 = '4.5.2';
|
394 |
var DATA_KEY$1 = 'bs.button';
|
395 |
var EVENT_KEY$1 = "." + DATA_KEY$1;
|
396 |
var DATA_API_KEY$1 = '.data-api';
|
525 |
return;
|
526 |
}
|
527 |
|
528 |
+
if (initialButton.tagName !== 'LABEL' || inputBtn && inputBtn.type !== 'checkbox') {
|
529 |
+
Button._jQueryInterface.call($(button), 'toggle');
|
530 |
}
|
|
|
|
|
531 |
}
|
532 |
}).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
|
533 |
var button = $(event.target).closest(SELECTOR_BUTTON)[0];
|
583 |
*/
|
584 |
|
585 |
var NAME$2 = 'carousel';
|
586 |
+
var VERSION$2 = '4.5.2';
|
587 |
var DATA_KEY$2 = 'bs.carousel';
|
588 |
var EVENT_KEY$2 = "." + DATA_KEY$2;
|
589 |
var DATA_API_KEY$2 = '.data-api';
|
770 |
;
|
771 |
|
772 |
_proto._getConfig = function _getConfig(config) {
|
773 |
+
config = _extends({}, Default, config);
|
774 |
Util.typeCheckConfig(NAME$2, config, DefaultType);
|
775 |
return config;
|
776 |
};
|
1060 |
return this.each(function () {
|
1061 |
var data = $(this).data(DATA_KEY$2);
|
1062 |
|
1063 |
+
var _config = _extends({}, Default, $(this).data());
|
1064 |
|
1065 |
if (typeof config === 'object') {
|
1066 |
+
_config = _extends({}, _config, config);
|
1067 |
}
|
1068 |
|
1069 |
var action = typeof config === 'string' ? config : _config.slide;
|
1101 |
return;
|
1102 |
}
|
1103 |
|
1104 |
+
var config = _extends({}, $(target).data(), $(this).data());
|
1105 |
|
1106 |
var slideIndex = this.getAttribute('data-slide-to');
|
1107 |
|
1170 |
*/
|
1171 |
|
1172 |
var NAME$3 = 'collapse';
|
1173 |
+
var VERSION$3 = '4.5.2';
|
1174 |
var DATA_KEY$3 = 'bs.collapse';
|
1175 |
var EVENT_KEY$3 = "." + DATA_KEY$3;
|
1176 |
var DATA_API_KEY$3 = '.data-api';
|
1385 |
;
|
1386 |
|
1387 |
_proto._getConfig = function _getConfig(config) {
|
1388 |
+
config = _extends({}, Default$1, config);
|
1389 |
config.toggle = Boolean(config.toggle); // Coerce string values
|
1390 |
|
1391 |
Util.typeCheckConfig(NAME$3, config, DefaultType$1);
|
1439 |
var $this = $(this);
|
1440 |
var data = $this.data(DATA_KEY$3);
|
1441 |
|
1442 |
+
var _config = _extends({}, Default$1, $this.data(), typeof config === 'object' && config ? config : {});
|
1443 |
|
1444 |
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
|
1445 |
_config.toggle = false;
|
1514 |
|
1515 |
/**!
|
1516 |
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
1517 |
+
* @version 1.16.1
|
1518 |
* @license
|
1519 |
* Copyright (c) 2016 Federico Zivolo and contributors
|
1520 |
*
|
1860 |
var sideA = axis === 'x' ? 'Left' : 'Top';
|
1861 |
var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
|
1862 |
|
1863 |
+
return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);
|
1864 |
}
|
1865 |
|
1866 |
function getSize(axis, body, html, computedStyle) {
|
1921 |
return obj;
|
1922 |
};
|
1923 |
|
1924 |
+
var _extends$1 = Object.assign || function (target) {
|
1925 |
for (var i = 1; i < arguments.length; i++) {
|
1926 |
var source = arguments[i];
|
1927 |
|
1943 |
* @returns {Object} ClientRect like output
|
1944 |
*/
|
1945 |
function getClientRect(offsets) {
|
1946 |
+
return _extends$1({}, offsets, {
|
1947 |
right: offsets.left + offsets.width,
|
1948 |
bottom: offsets.top + offsets.height
|
1949 |
});
|
2015 |
var scrollParent = getScrollParent(children);
|
2016 |
|
2017 |
var styles = getStyleComputedProperty(parent);
|
2018 |
+
var borderTopWidth = parseFloat(styles.borderTopWidth);
|
2019 |
+
var borderLeftWidth = parseFloat(styles.borderLeftWidth);
|
2020 |
|
2021 |
// In cases where the parent is fixed, we must ignore negative scroll in offset calc
|
2022 |
if (fixedPosition && isHTML) {
|
2037 |
// differently when margins are applied to it. The margins are included in
|
2038 |
// the box of the documentElement, in the other cases not.
|
2039 |
if (!isIE10 && isHTML) {
|
2040 |
+
var marginTop = parseFloat(styles.marginTop);
|
2041 |
+
var marginLeft = parseFloat(styles.marginLeft);
|
2042 |
|
2043 |
offsets.top -= borderTopWidth - marginTop;
|
2044 |
offsets.bottom -= borderTopWidth - marginTop;
|
2231 |
};
|
2232 |
|
2233 |
var sortedAreas = Object.keys(rects).map(function (key) {
|
2234 |
+
return _extends$1({
|
2235 |
key: key
|
2236 |
}, rects[key], {
|
2237 |
area: getArea(rects[key])
|
2873 |
};
|
2874 |
|
2875 |
// Update `data` attributes, styles and arrowStyles
|
2876 |
+
data.attributes = _extends$1({}, attributes, data.attributes);
|
2877 |
+
data.styles = _extends$1({}, styles, data.styles);
|
2878 |
+
data.arrowStyles = _extends$1({}, data.offsets.arrow, data.arrowStyles);
|
2879 |
|
2880 |
return data;
|
2881 |
}
|
2977 |
// Compute the sideValue using the updated popper offsets
|
2978 |
// take popper margin in account because we don't have this info available
|
2979 |
var css = getStyleComputedProperty(data.instance.popper);
|
2980 |
+
var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);
|
2981 |
+
var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);
|
2982 |
var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
|
2983 |
|
2984 |
// prevent arrowElement from being placed not contiguously to its popper
|
3155 |
|
3156 |
// this object contains `position`, we want to preserve it along with
|
3157 |
// any additional property we may add in the future
|
3158 |
+
data.offsets.popper = _extends$1({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
|
3159 |
|
3160 |
data = runModifiers(data.instance.modifiers, data, 'flip');
|
3161 |
}
|
3429 |
|
3430 |
order.forEach(function (placement) {
|
3431 |
var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
|
3432 |
+
popper = _extends$1({}, popper, check[side](placement));
|
3433 |
});
|
3434 |
|
3435 |
data.offsets.popper = popper;
|
3464 |
end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
|
3465 |
};
|
3466 |
|
3467 |
+
data.offsets.popper = _extends$1({}, popper, shiftOffsets[shiftvariation]);
|
3468 |
}
|
3469 |
|
3470 |
return data;
|
3996 |
this.update = debounce(this.update.bind(this));
|
3997 |
|
3998 |
// with {} we create a new object with the options inside it
|
3999 |
+
this.options = _extends$1({}, Popper.Defaults, options);
|
4000 |
|
4001 |
// init state
|
4002 |
this.state = {
|
4011 |
|
4012 |
// Deep merge modifiers options
|
4013 |
this.options.modifiers = {};
|
4014 |
+
Object.keys(_extends$1({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
|
4015 |
+
_this.options.modifiers[name] = _extends$1({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
|
4016 |
});
|
4017 |
|
4018 |
// Refactoring modifiers' list (Object => Array)
|
4019 |
this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
|
4020 |
+
return _extends$1({
|
4021 |
name: name
|
4022 |
}, _this.options.modifiers[name]);
|
4023 |
})
|
4133 |
*/
|
4134 |
|
4135 |
var NAME$4 = 'dropdown';
|
4136 |
+
var VERSION$4 = '4.5.2';
|
4137 |
var DATA_KEY$4 = 'bs.dropdown';
|
4138 |
var EVENT_KEY$4 = "." + DATA_KEY$4;
|
4139 |
var DATA_API_KEY$4 = '.data-api';
|
4360 |
};
|
4361 |
|
4362 |
_proto._getConfig = function _getConfig(config) {
|
4363 |
+
config = _extends({}, this.constructor.Default, $(this._element).data(), config);
|
4364 |
Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
|
4365 |
return config;
|
4366 |
};
|
4405 |
|
4406 |
if (typeof this._config.offset === 'function') {
|
4407 |
offset.fn = function (data) {
|
4408 |
+
data.offsets = _extends({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {});
|
4409 |
return data;
|
4410 |
};
|
4411 |
} else {
|
4435 |
};
|
4436 |
}
|
4437 |
|
4438 |
+
return _extends({}, popperConfig, this._config.popperConfig);
|
4439 |
} // Static
|
4440 |
;
|
4441 |
|
4647 |
*/
|
4648 |
|
4649 |
var NAME$5 = 'modal';
|
4650 |
+
var VERSION$5 = '4.5.2';
|
4651 |
var DATA_KEY$5 = 'bs.modal';
|
4652 |
var EVENT_KEY$5 = "." + DATA_KEY$5;
|
4653 |
var DATA_API_KEY$5 = '.data-api';
|
4839 |
;
|
4840 |
|
4841 |
_proto._getConfig = function _getConfig(config) {
|
4842 |
+
config = _extends({}, Default$3, config);
|
4843 |
Util.typeCheckConfig(NAME$5, config, DefaultType$3);
|
4844 |
return config;
|
4845 |
};
|
4855 |
return;
|
4856 |
}
|
4857 |
|
4858 |
+
var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
4859 |
+
|
4860 |
+
if (!isModalOverflowing) {
|
4861 |
+
this._element.style.overflowY = 'hidden';
|
4862 |
+
}
|
4863 |
+
|
4864 |
this._element.classList.add(CLASS_NAME_STATIC);
|
4865 |
|
4866 |
+
var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog);
|
4867 |
+
$(this._element).off(Util.TRANSITION_END);
|
4868 |
$(this._element).one(Util.TRANSITION_END, function () {
|
4869 |
_this3._element.classList.remove(CLASS_NAME_STATIC);
|
4870 |
+
|
4871 |
+
if (!isModalOverflowing) {
|
4872 |
+
$(_this3._element).one(Util.TRANSITION_END, function () {
|
4873 |
+
_this3._element.style.overflowY = '';
|
4874 |
+
}).emulateTransitionEnd(_this3._element, modalTransitionDuration);
|
4875 |
+
}
|
4876 |
}).emulateTransitionEnd(modalTransitionDuration);
|
4877 |
|
4878 |
this._element.focus();
|
4898 |
|
4899 |
this._element.setAttribute('aria-modal', true);
|
4900 |
|
4901 |
+
this._element.setAttribute('role', 'dialog');
|
4902 |
+
|
4903 |
if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
|
4904 |
modalBody.scrollTop = 0;
|
4905 |
} else {
|
4987 |
|
4988 |
this._element.removeAttribute('aria-modal');
|
4989 |
|
4990 |
+
this._element.removeAttribute('role');
|
4991 |
+
|
4992 |
this._isTransitioning = false;
|
4993 |
|
4994 |
this._showBackdrop(function () {
|
5170 |
return this.each(function () {
|
5171 |
var data = $(this).data(DATA_KEY$5);
|
5172 |
|
5173 |
+
var _config = _extends({}, Default$3, $(this).data(), typeof config === 'object' && config ? config : {});
|
5174 |
|
5175 |
if (!data) {
|
5176 |
data = new Modal(this, _config);
|
5220 |
target = document.querySelector(selector);
|
5221 |
}
|
5222 |
|
5223 |
+
var config = $(target).data(DATA_KEY$5) ? 'toggle' : _extends({}, $(target).data(), $(this).data());
|
5224 |
|
5225 |
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
5226 |
event.preventDefault();
|
5257 |
|
5258 |
/**
|
5259 |
* --------------------------------------------------------------------------
|
5260 |
+
* Bootstrap (v4.5.2): tools/sanitizer.js
|
5261 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5262 |
* --------------------------------------------------------------------------
|
5263 |
*/
|
5264 |
var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
|
5383 |
*/
|
5384 |
|
5385 |
var NAME$6 = 'tooltip';
|
5386 |
+
var VERSION$6 = '4.5.2';
|
5387 |
var DATA_KEY$6 = 'bs.tooltip';
|
5388 |
var EVENT_KEY$6 = "." + DATA_KEY$6;
|
5389 |
var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
|
5771 |
return _this3._handlePopperPlacementChange(data);
|
5772 |
}
|
5773 |
};
|
5774 |
+
return _extends({}, defaultBsConfig, this.config.popperConfig);
|
5775 |
};
|
5776 |
|
5777 |
_proto._getOffset = function _getOffset() {
|
5781 |
|
5782 |
if (typeof this.config.offset === 'function') {
|
5783 |
offset.fn = function (data) {
|
5784 |
+
data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element) || {});
|
5785 |
return data;
|
5786 |
};
|
5787 |
} else {
|
5836 |
$(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
|
5837 |
|
5838 |
if (this.config.selector) {
|
5839 |
+
this.config = _extends({}, this.config, {
|
5840 |
trigger: 'manual',
|
5841 |
selector: ''
|
5842 |
});
|
5936 |
delete dataAttributes[dataAttr];
|
5937 |
}
|
5938 |
});
|
5939 |
+
config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
|
5940 |
|
5941 |
if (typeof config.delay === 'number') {
|
5942 |
config.delay = {
|
6095 |
*/
|
6096 |
|
6097 |
var NAME$7 = 'popover';
|
6098 |
+
var VERSION$7 = '4.5.2';
|
6099 |
var DATA_KEY$7 = 'bs.popover';
|
6100 |
var EVENT_KEY$7 = "." + DATA_KEY$7;
|
6101 |
var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
|
6102 |
var CLASS_PREFIX$1 = 'bs-popover';
|
6103 |
var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
|
6104 |
|
6105 |
+
var Default$5 = _extends({}, Tooltip.Default, {
|
6106 |
placement: 'right',
|
6107 |
trigger: 'click',
|
6108 |
content: '',
|
6109 |
template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
|
6110 |
});
|
6111 |
|
6112 |
+
var DefaultType$5 = _extends({}, Tooltip.DefaultType, {
|
6113 |
content: '(string|element|function)'
|
6114 |
});
|
6115 |
|
6275 |
*/
|
6276 |
|
6277 |
var NAME$8 = 'scrollspy';
|
6278 |
+
var VERSION$8 = '4.5.2';
|
6279 |
var DATA_KEY$8 = 'bs.scrollspy';
|
6280 |
var EVENT_KEY$8 = "." + DATA_KEY$8;
|
6281 |
var DATA_API_KEY$6 = '.data-api';
|
6389 |
;
|
6390 |
|
6391 |
_proto._getConfig = function _getConfig(config) {
|
6392 |
+
config = _extends({}, Default$6, typeof config === 'object' && config ? config : {});
|
6393 |
|
6394 |
if (typeof config.target !== 'string' && Util.isElement(config.target)) {
|
6395 |
var id = $(config.target).attr('id');
|
6567 |
*/
|
6568 |
|
6569 |
var NAME$9 = 'tab';
|
6570 |
+
var VERSION$9 = '4.5.2';
|
6571 |
var DATA_KEY$9 = 'bs.tab';
|
6572 |
var EVENT_KEY$9 = "." + DATA_KEY$9;
|
6573 |
var DATA_API_KEY$7 = '.data-api';
|
6793 |
*/
|
6794 |
|
6795 |
var NAME$a = 'toast';
|
6796 |
+
var VERSION$a = '4.5.2';
|
6797 |
var DATA_KEY$a = 'bs.toast';
|
6798 |
var EVENT_KEY$a = "." + DATA_KEY$a;
|
6799 |
var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
|
6846 |
return;
|
6847 |
}
|
6848 |
|
6849 |
+
this._clearTimeout();
|
6850 |
+
|
6851 |
if (this._config.animation) {
|
6852 |
this._element.classList.add(CLASS_NAME_FADE$5);
|
6853 |
}
|
6896 |
};
|
6897 |
|
6898 |
_proto.dispose = function dispose() {
|
6899 |
+
this._clearTimeout();
|
|
|
6900 |
|
6901 |
if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
|
6902 |
this._element.classList.remove(CLASS_NAME_SHOW$7);
|
6910 |
;
|
6911 |
|
6912 |
_proto._getConfig = function _getConfig(config) {
|
6913 |
+
config = _extends({}, Default$7, $(this._element).data(), typeof config === 'object' && config ? config : {});
|
6914 |
Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
|
6915 |
return config;
|
6916 |
};
|
6940 |
} else {
|
6941 |
complete();
|
6942 |
}
|
6943 |
+
};
|
6944 |
+
|
6945 |
+
_proto._clearTimeout = function _clearTimeout() {
|
6946 |
+
clearTimeout(this._timeout);
|
6947 |
+
this._timeout = null;
|
6948 |
} // Static
|
6949 |
;
|
6950 |
|
resources/js/bootstrap4.bundle.min.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
/*!
|
2 |
-
* Bootstrap v4.5.
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
5 |
*/
|
6 |
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t=t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function r(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function s(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?r(Object(n),!0).forEach((function(e){o(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;function a(t){var n=this,i=!1;return e(this).one(l.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||l.triggerTransitionEnd(n)}),t),this}var l={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),r=parseFloat(i);return o||r?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],r=e[i],s=r&&l.isElement(r)?"element":null===(a=r)||"undefined"==typeof a?""+a:{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}var a},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?l.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};l.jQueryDetection(),e.fn.emulateTransitionEnd=a,e.event.special[l.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var c="alert",u=e.fn[c],h=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=l.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=l.getTransitionDurationFromElement(t);e(t).one(l.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),e.fn[c]=h._jQueryInterface,e.fn[c].Constructor=h,e.fn[c].noConflict=function(){return e.fn[c]=u,h._jQueryInterface};var f=e.fn.button,d=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var r=i.querySelector(".active");r&&e(r).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();"LABEL"===i.tagName&&o&&"checkbox"===o.type&&t.preventDefault(),d._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var r=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;r<s;r++){var a=t[r];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=d._jQueryInterface,e.fn.button.Constructor=d,e.fn.button.noConflict=function(){return e.fn.button=f,d._jQueryInterface};var p="carousel",m=".bs.carousel",g=e.fn[p],v={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},b={TOUCH:"touch",PEN:"pen"},y=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(l.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(m),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=s(s({},v),t),l.typeCheckConfig(p,t,_),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&b[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(r),r},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,r,s=this,a=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(a),u=n||a&&this._getItemByDirection(t,a),h=this._getItemIndex(u),f=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",r="left"):(i="carousel-item-right",o="carousel-item-prev",r="right"),u&&e(u).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(u,r).isDefaultPrevented()&&a&&u){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(u);var d=e.Event("slid.bs.carousel",{relatedTarget:u,direction:r,from:c,to:h});if(e(this._element).hasClass("slide")){e(u).addClass(o),l.reflow(u),e(a).addClass(i),e(u).addClass(i);var p=parseInt(u.getAttribute("data-interval"),10);p?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=p):this._config.interval=this._config.defaultInterval||this._config.interval;var m=l.getTransitionDurationFromElement(a);e(a).one(l.TRANSITION_END,(function(){e(u).removeClass(i+" "+o).addClass("active"),e(a).removeClass("active "+o+" "+i),s._isSliding=!1,setTimeout((function(){return e(s._element).trigger(d)}),0)})).emulateTransitionEnd(m)}else e(a).removeClass("active"),e(u).addClass("active"),this._isSliding=!1,e(this._element).trigger(d);f&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),o=s(s({},v),e(this).data());"object"==typeof n&&(o=s(s({},o),n));var r="string"==typeof n?n:o.slide;if(i||(i=new t(this,o),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof r){if("undefined"==typeof i[r])throw new TypeError('No method named "'+r+'"');i[r]()}else o.interval&&o.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=l.getSelectorFromElement(this);if(i){var o=e(i)[0];if(o&&e(o).hasClass("carousel")){var r=s(s({},e(o).data()),e(this).data()),a=this.getAttribute("data-slide-to");a&&(r.interval=!1),t._jQueryInterface.call(e(o),r),a&&e(o).data("bs.carousel").to(a),n.preventDefault()}}},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return v}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",y._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);y._jQueryInterface.call(o,o.data())}})),e.fn[p]=y._jQueryInterface,e.fn[p].Constructor=y,e.fn[p].noConflict=function(){return e.fn[p]=g,y._jQueryInterface};var w="collapse",E=e.fn[w],T={toggle:!0,parent:""},C={toggle:"boolean",parent:"(string|element)"},S=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var r=n[i],s=l.getSelectorFromElement(r),a=[].slice.call(document.querySelectorAll(s)).filter((function(e){return e===t}));null!==s&&a.length>0&&(this._selector=s,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var r=e.Event("show.bs.collapse");if(e(this._element).trigger(r),!r.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var s=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[s]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var a="scroll"+(s[0].toUpperCase()+s.slice(1)),c=l.getTransitionDurationFromElement(this._element);e(this._element).one(l.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[s]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[s]=this._element[a]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",l.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r<o;r++){var s=this._triggerArray[r],a=l.getSelectorFromElement(s);if(null!==a)e([].slice.call(document.querySelectorAll(a))).hasClass("show")||e(s).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var c=l.getTransitionDurationFromElement(this._element);e(this._element).one(l.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(c)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=s(s({},T),t)).toggle=Boolean(t.toggle),l.typeCheckConfig(w,t,C),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;l.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',r=[].slice.call(n.querySelectorAll(o));return e(r).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=l.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.collapse"),r=s(s(s({},T),i.data()),"object"==typeof n&&n?n:{});if(!o&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),o||(o=new t(this,r),i.data("bs.collapse",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return T}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=l.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();S._jQueryInterface.call(t,i)}))})),e.fn[w]=S._jQueryInterface,e.fn[w].Constructor=S,e.fn[w].noConflict=function(){return e.fn[w]=E,S._jQueryInterface};var D="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,k=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(D&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var N=D&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),k))}};function O(t){return t&&"[object Function]"==={}.toString.call(t)}function A(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function I(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function x(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=A(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:x(I(t))}function j(t){return t&&t.referenceNode?t.referenceNode:t}var L=D&&!(!window.MSInputMethodContext||!document.documentMode),P=D&&/MSIE 10/.test(navigator.userAgent);function F(t){return 11===t?L:10===t?P:L||P}function R(t){if(!t)return document.documentElement;for(var e=F(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===A(n,"position")?R(n):n:t?t.ownerDocument.documentElement:document.documentElement}function M(t){return null!==t.parentNode?M(t.parentNode):t}function B(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var s,a,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(a=(s=l).nodeName)||"HTML"!==a&&R(s.firstElementChild)!==s?R(l):l;var c=M(t);return c.host?B(c.host,e):B(t,M(e).host)}function q(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function H(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=q(e,"top"),o=q(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Q(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"],10)+parseFloat(t["border"+i+"Width"],10)}function W(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],F(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function U(t){var e=t.body,n=t.documentElement,i=F(10)&&getComputedStyle(n);return{height:W("Height",e,n,i),width:W("Width",e,n,i)}}var V=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},Y=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),z=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},X=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function K(t){return X({},t,{right:t.left+t.width,bottom:t.top+t.height})}function G(t){var e={};try{if(F(10)){e=t.getBoundingClientRect();var n=q(t,"top"),i=q(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?U(t.ownerDocument):{},s=r.width||t.clientWidth||o.width,a=r.height||t.clientHeight||o.height,l=t.offsetWidth-s,c=t.offsetHeight-a;if(l||c){var u=A(t);l-=Q(u,"x"),c-=Q(u,"y"),o.width-=l,o.height-=c}return K(o)}function $(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=F(10),o="HTML"===e.nodeName,r=G(t),s=G(e),a=x(t),l=A(e),c=parseFloat(l.borderTopWidth,10),u=parseFloat(l.borderLeftWidth,10);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var h=K({top:r.top-s.top-c,left:r.left-s.left-u,width:r.width,height:r.height});if(h.marginTop=0,h.marginLeft=0,!i&&o){var f=parseFloat(l.marginTop,10),d=parseFloat(l.marginLeft,10);h.top-=c-f,h.bottom-=c-f,h.left-=u-d,h.right-=u-d,h.marginTop=f,h.marginLeft=d}return(i&&!n?e.contains(a):e===a&&"BODY"!==a.nodeName)&&(h=H(h,e)),h}function J(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=$(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),s=e?0:q(n),a=e?0:q(n,"left"),l={top:s-i.top+i.marginTop,left:a-i.left+i.marginLeft,width:o,height:r};return K(l)}function Z(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===A(t,"position"))return!0;var n=I(t);return!!n&&Z(n)}function tt(t){if(!t||!t.parentElement||F())return document.documentElement;for(var e=t.parentElement;e&&"none"===A(e,"transform");)e=e.parentElement;return e||document.documentElement}function et(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},s=o?tt(t):B(t,j(e));if("viewport"===i)r=J(s,o);else{var a=void 0;"scrollParent"===i?"BODY"===(a=x(I(e))).nodeName&&(a=t.ownerDocument.documentElement):a="window"===i?t.ownerDocument.documentElement:i;var l=$(a,s,o);if("HTML"!==a.nodeName||Z(s))r=l;else{var c=U(t.ownerDocument),u=c.height,h=c.width;r.top+=l.top-l.marginTop,r.bottom=u+l.top,r.left+=l.left-l.marginLeft,r.right=h+l.left}}var f="number"==typeof(n=n||0);return r.left+=f?n:n.left||0,r.top+=f?n:n.top||0,r.right-=f?n:n.right||0,r.bottom-=f?n:n.bottom||0,r}function nt(t){return t.width*t.height}function it(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=et(n,i,r,o),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map((function(t){return X({key:t},a[t],{area:nt(a[t])})})).sort((function(t,e){return e.area-t.area})),c=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),u=c.length>0?c[0].key:l[0].key,h=t.split("-")[1];return u+(h?"-"+h:"")}function ot(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?tt(e):B(e,j(n));return $(n,o,i)}function rt(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function st(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function at(t,e,n){n=n.split("-")[0];var i=rt(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),s=r?"top":"left",a=r?"left":"top",l=r?"height":"width",c=r?"width":"height";return o[s]=e[s]+e[l]/2-i[l]/2,o[a]=n===a?e[a]-i[c]:e[st(a)],o}function lt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function ct(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=lt(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&O(n)&&(e.offsets.popper=K(e.offsets.popper),e.offsets.reference=K(e.offsets.reference),e=n(e,t))})),e}function ut(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=ot(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=it(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=at(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=ct(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function ht(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ft(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length;i++){var o=e[i],r=o?""+o+n:t;if("undefined"!=typeof document.body.style[r])return r}return null}function dt(){return this.state.isDestroyed=!0,ht(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[ft("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function pt(t){var e=t.ownerDocument;return e?e.defaultView:window}function mt(t,e,n,i){n.updateBound=i,pt(t).addEventListener("resize",n.updateBound,{passive:!0});var o=x(t);return function t(e,n,i,o){var r="BODY"===e.nodeName,s=r?e.ownerDocument.defaultView:e;s.addEventListener(n,i,{passive:!0}),r||t(x(s.parentNode),n,i,o),o.push(s)}(o,"scroll",n.updateBound,n.scrollParents),n.scrollElement=o,n.eventsEnabled=!0,n}function gt(){this.state.eventsEnabled||(this.state=mt(this.reference,this.options,this.state,this.scheduleUpdate))}function vt(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,pt(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function _t(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function bt(t,e){Object.keys(e).forEach((function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&&_t(e[n])&&(i="px"),t.style[n]=e[n]+i}))}var yt=D&&/Firefox/i.test(navigator.userAgent);function wt(t,e,n){var i=lt(t,(function(t){return t.name===e})),o=!!i&&t.some((function(t){return t.name===n&&t.enabled&&t.order<i.order}));if(!o){var r="`"+e+"`",s="`"+n+"`";console.warn(s+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var Et=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],Tt=Et.slice(3);function Ct(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=Tt.indexOf(t),i=Tt.slice(n+1).concat(Tt.slice(0,n));return e?i.reverse():i}var St="flip",Dt="clockwise",kt="counterclockwise";function Nt(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),s=t.split(/(\+|\-)/).map((function(t){return t.trim()})),a=s.indexOf(lt(s,(function(t){return-1!==t.search(/,|\s/)})));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map((function(t,i){var o=(1===i?!r:r)?"height":"width",s=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],s=o[2];if(!r)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=i}return K(a)[e]/100*r}if("vh"===s||"vw"===s){return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){_t(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var Ot={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,s=o.popper,a=-1!==["bottom","top"].indexOf(n),l=a?"left":"top",c=a?"width":"height",u={start:z({},l,r[l]),end:z({},l,r[l]+r[c]-s[c])};t.offsets.popper=X({},s,u[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,s=o.reference,a=i.split("-")[0],l=void 0;return l=_t(+n)?[+n,0]:Nt(n,r,s,a),"left"===a?(r.top+=l[0],r.left-=l[1]):"right"===a?(r.top+=l[0],r.left+=l[1]):"top"===a?(r.left+=l[0],r.top-=l[1]):"bottom"===a&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||R(t.instance.popper);t.instance.reference===n&&(n=R(n));var i=ft("transform"),o=t.instance.popper.style,r=o.top,s=o.left,a=o[i];o.top="",o.left="",o[i]="";var l=et(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=s,o[i]=a,e.boundaries=l;var c=e.priority,u=t.offsets.popper,h={primary:function(t){var n=u[t];return u[t]<l[t]&&!e.escapeWithReference&&(n=Math.max(u[t],l[t])),z({},t,n)},secondary:function(t){var n="right"===t?"left":"top",i=u[n];return u[t]>l[t]&&!e.escapeWithReference&&(i=Math.min(u[n],l[t]-("right"===t?u.width:u.height))),z({},n,i)}};return c.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";u=X({},u,h[e](t))})),t.offsets.popper=u,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]<r(i[l])&&(t.offsets.popper[l]=r(i[l])-n[c]),n[l]>r(i[a])&&(t.offsets.popper[l]=r(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!wt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",u=l?"Top":"Left",h=u.toLowerCase(),f=l?"left":"top",d=l?"bottom":"right",p=rt(i)[c];a[d]-p<s[h]&&(t.offsets.popper[h]-=s[h]-(a[d]-p)),a[h]+p>s[d]&&(t.offsets.popper[h]+=a[h]+p-s[d]),t.offsets.popper=K(t.offsets.popper);var m=a[h]+a[c]/2-p/2,g=A(t.instance.popper),v=parseFloat(g["margin"+u],10),_=parseFloat(g["border"+u+"Width"],10),b=m-t.offsets.popper[h]-v-_;return b=Math.max(Math.min(s[c]-p,b),0),t.arrowElement=i,t.offsets.arrow=(z(n={},h,Math.round(b)),z(n,f,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(ht(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=et(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=st(i),r=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case St:s=[i,o];break;case Dt:s=Ct(i);break;case kt:s=Ct(i,!0);break;default:s=e.behavior}return s.forEach((function(a,l){if(i!==a||s.length===l+1)return t;i=t.placement.split("-")[0],o=st(i);var c=t.offsets.popper,u=t.offsets.reference,h=Math.floor,f="left"===i&&h(c.right)>h(u.left)||"right"===i&&h(c.left)<h(u.right)||"top"===i&&h(c.bottom)>h(u.top)||"bottom"===i&&h(c.top)<h(u.bottom),d=h(c.left)<h(n.left),p=h(c.right)>h(n.right),m=h(c.top)<h(n.top),g=h(c.bottom)>h(n.bottom),v="left"===i&&d||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,_=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(_&&"start"===r&&d||_&&"end"===r&&p||!_&&"start"===r&&m||!_&&"end"===r&&g),y=!!e.flipVariationsByContent&&(_&&"start"===r&&p||_&&"end"===r&&d||!_&&"start"===r&&g||!_&&"end"===r&&m),w=b||y;(f||v||w)&&(t.flipped=!0,(f||v)&&(i=s[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=X({},t.offsets.popper,at(t.instance.popper,t.offsets.reference,t.placement)),t=ct(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return o[s?"left":"top"]=r[n]-(a?o[s?"width":"height"]:0),t.placement=st(e),t.offsets.popper=K(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!wt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=lt(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,o=t.offsets.popper,r=lt(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var s=void 0!==r?r:e.gpuAcceleration,a=R(t.instance.popper),l=G(a),c={position:o.position},u=function(t,e){var n=t.offsets,i=n.popper,o=n.reference,r=Math.round,s=Math.floor,a=function(t){return t},l=r(o.width),c=r(i.width),u=-1!==["left","right"].indexOf(t.placement),h=-1!==t.placement.indexOf("-"),f=e?u||h||l%2==c%2?r:s:a,d=e?r:a;return{left:f(l%2==1&&c%2==1&&!h&&e?i.left-1:i.left),top:d(i.top),bottom:d(i.bottom),right:f(i.right)}}(t,window.devicePixelRatio<2||!yt),h="bottom"===n?"top":"bottom",f="right"===i?"left":"right",d=ft("transform"),p=void 0,m=void 0;if(m="bottom"===h?"HTML"===a.nodeName?-a.clientHeight+u.bottom:-l.height+u.bottom:u.top,p="right"===f?"HTML"===a.nodeName?-a.clientWidth+u.right:-l.width+u.right:u.left,s&&d)c[d]="translate3d("+p+"px, "+m+"px, 0)",c[h]=0,c[f]=0,c.willChange="transform";else{var g="bottom"===h?-1:1,v="right"===f?-1:1;c[h]=m*g,c[f]=p*v,c.willChange=h+", "+f}var _={"x-placement":t.placement};return t.attributes=X({},_,t.attributes),t.styles=X({},c,t.styles),t.arrowStyles=X({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){var e,n;return bt(t.instance.popper,t.styles),e=t.instance.popper,n=t.attributes,Object.keys(n).forEach((function(t){!1!==n[t]?e.setAttribute(t,n[t]):e.removeAttribute(t)})),t.arrowElement&&Object.keys(t.arrowStyles).length&&bt(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,o){var r=ot(o,e,t,n.positionFixed),s=it(n.placement,r,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",s),bt(e,{position:n.positionFixed?"fixed":"absolute"}),n},gpuAcceleration:void 0}}},At=function(){function t(e,n){var i=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};V(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=N(this.update.bind(this)),this.options=X({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(X({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=X({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return X({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&O(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return Y(t,[{key:"update",value:function(){return ut.call(this)}},{key:"destroy",value:function(){return dt.call(this)}},{key:"enableEventListeners",value:function(){return gt.call(this)}},{key:"disableEventListeners",value:function(){return vt.call(this)}}]),t}();At.Utils=("undefined"!=typeof window?window:global).PopperUtils,At.placements=Et,At.Defaults=Ot;var It="dropdown",xt=e.fn[It],jt=new RegExp("38|40|27"),Lt={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},Pt={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},Ft=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var n=t.prototype;return n.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},n.show=function(n){if(void 0===n&&(n=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var i={relatedTarget:this._element},o=e.Event("show.bs.dropdown",i),r=t._getParentFromElement(this._element);if(e(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&n){if("undefined"==typeof At)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var s=this._element;"parent"===this._config.reference?s=r:l.isElement(this._config.reference)&&(s=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(s=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new At(s,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",i))}}},n.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},n.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},n.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},n._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},n._getConfig=function(t){return t=s(s(s({},this.constructor.Default),e(this._element).data()),t),l.typeCheckConfig(It,t,this.constructor.DefaultType),t},n._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},n._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},n._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},n._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=s(s({},e.offsets),t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},n._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),s(s({},t),this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,r=i.length;o<r;o++){var s=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(s).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(s,n.target))){var u=e.Event("hide.bs.dropdown",l);e(s).trigger(u),u.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(s).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=l.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!jt.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var r=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==r.length){var s=r.indexOf(n.target);38===n.which&&s>0&&s--,40===n.which&&s<r.length-1&&s++,s<0&&(s=0),r[s].focus()}}}},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return Lt}},{key:"DefaultType",get:function(){return Pt}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',Ft._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",Ft._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",Ft._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),Ft._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[It]=Ft._jQueryInterface,e.fn[It].Constructor=Ft,e.fn[It].noConflict=function(){return e.fn[It]=xt,Ft._jQueryInterface};var Rt=e.fn.modal,Mt={backdrop:!0,keyboard:!0,focus:!0,show:!0},Bt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},qt=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var r=l.getTransitionDurationFromElement(this._element);e(this._element).one(l.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(r)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=s(s({},Mt),t),l.typeCheckConfig("modal",t,Bt),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;this._element.classList.add("modal-static");var i=l.getTransitionDurationFromElement(this._element);e(this._element).one(l.TRANSITION_END,(function(){t._element.classList.remove("modal-static")})).emulateTransitionEnd(i),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&l.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=e.Event("shown.bs.modal",{relatedTarget:t}),s=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(r)};if(i){var a=l.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(l.TRANSITION_END,s).emulateTransitionEnd(a)}else s()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&l.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=l.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(l.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var r=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var s=l.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(l.TRANSITION_END,r).emulateTransitionEnd(s)}else r()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,r=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(r)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,r=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(r)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,r=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(r)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var o=e(this).data("bs.modal"),r=s(s(s({},Mt),e(this).data()),"object"==typeof n&&n?n:{});if(o||(o=new t(this,r),e(this).data("bs.modal",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](i)}else r.show&&o.show(i)}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return Mt}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,o=l.getSelectorFromElement(this);o&&(n=document.querySelector(o));var r=e(n).data("bs.modal")?"toggle":s(s({},e(n).data()),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var a=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||a.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));qt._jQueryInterface.call(e(n),r,this)})),e.fn.modal=qt._jQueryInterface,e.fn.modal.Constructor=qt,e.fn.modal.noConflict=function(){return e.fn.modal=Rt,qt._jQueryInterface};var Ht=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Qt={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Wt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,Ut=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Vt(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),r=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=r[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[s]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===Ht.indexOf(n)||Boolean(t.nodeValue.match(Wt)||t.nodeValue.match(Ut));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,r=i.length;o<r;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=r.length;a<l;a++)s(a);return i.body.innerHTML}var Yt="tooltip",zt=e.fn[Yt],Xt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Kt=["sanitize","whiteList","sanitizeFn"],Gt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},$t={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Jt={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Qt,popperConfig:null},Zt={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},te=function(){function t(t,e){if("undefined"==typeof At)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var n=t.prototype;return n.enable=function(){this._isEnabled=!0},n.disable=function(){this._isEnabled=!1},n.toggleEnabled=function(){this._isEnabled=!this._isEnabled},n.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},n.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},n.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var n=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(n);var i=l.findShadowRoot(this.element),o=e.contains(null!==i?i:this.element.ownerDocument.documentElement,this.element);if(n.isDefaultPrevented()||!o)return;var r=this.getTipElement(),s=l.getUID(this.constructor.NAME);r.setAttribute("id",s),this.element.setAttribute("aria-describedby",s),this.setContent(),this.config.animation&&e(r).addClass("fade");var a="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,c=this._getAttachment(a);this.addAttachmentClass(c);var u=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(u),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new At(this.element,r,this._getPopperConfig(c)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var h=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=l.getTransitionDurationFromElement(this.tip);e(this.tip).one(l.TRANSITION_END,h).emulateTransitionEnd(f)}else h()}},n.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),r=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var s=l.getTransitionDurationFromElement(i);e(i).one(l.TRANSITION_END,r).emulateTransitionEnd(s)}else r();this._hoverState=""}},n.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},n.isWithContent=function(){return Boolean(this.getTitle())},n.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},n.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},n.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},n.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Vt(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},n.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},n._getPopperConfig=function(t){var e=this;return s(s({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),this.config.popperConfig)},n._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=s(s({},e.offsets),t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},n._getContainer=function(){return!1===this.config.container?document.body:l.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},n._getAttachment=function(t){return $t[t.toUpperCase()]},n._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s(s({},this.config),{},{trigger:"manual",selector:""}):this._fixTitle()},n._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},n._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},n._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},n._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},n._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==Kt.indexOf(t)&&delete n[t]})),"number"==typeof(t=s(s(s({},this.constructor.Default),n),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),l.typeCheckConfig(Yt,t,this.constructor.DefaultType),t.sanitize&&(t.template=Vt(t.template,t.whiteList,t.sanitizeFn)),t},n._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},n._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(Xt);null!==n&&n.length&&t.removeClass(n.join(""))},n._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},n._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return Jt}},{key:"NAME",get:function(){return Yt}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Zt}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Gt}}]),t}();e.fn[Yt]=te._jQueryInterface,e.fn[Yt].Constructor=te,e.fn[Yt].noConflict=function(){return e.fn[Yt]=zt,te._jQueryInterface};var ee="popover",ne=e.fn[ee],ie=new RegExp("(^|\\s)bs-popover\\S+","g"),oe=s(s({},te.Default),{},{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),re=s(s({},te.DefaultType),{},{content:"(string|element|function)"}),se={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},ae=function(t){var n,o;function r(){return t.apply(this,arguments)||this}o=t,(n=r).prototype=Object.create(o.prototype),n.prototype.constructor=n,n.__proto__=o;var s=r.prototype;return s.isWithContent=function(){return this.getTitle()||this._getContent()},s.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},s.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},s.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},s._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},s._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(ie);null!==n&&n.length>0&&t.removeClass(n.join(""))},r._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new r(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},i(r,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return oe}},{key:"NAME",get:function(){return ee}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return se}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return re}}]),r}(te);e.fn[ee]=ae._jQueryInterface,e.fn[ee].Constructor=ae,e.fn[ee].noConflict=function(){return e.fn[ee]=ne,ae._jQueryInterface};var le="scrollspy",ce=e.fn[le],ue={offset:10,method:"auto",target:""},he={offset:"number",method:"string",target:"(string|element)"},fe=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,r=l.getSelectorFromElement(t);if(r&&(n=document.querySelector(r)),n){var s=n.getBoundingClientRect();if(s.width||s.height)return[e(n)[i]().top+o,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=s(s({},ue),"object"==typeof t&&t?t:{})).target&&l.isElement(t.target)){var n=e(t.target).attr("id");n||(n=l.getUID(le),e(t.target).attr("id",n)),t.target="#"+n}return l.typeCheckConfig(le,t,he),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return ue}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);fe._jQueryInterface.call(i,i.data())}})),e.fn[le]=fe._jQueryInterface,e.fn[le].Constructor=fe,e.fn[le].noConflict=function(){return e.fn[le]=ce,fe._jQueryInterface};var de=e.fn.tab,pe=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],r=l.getSelectorFromElement(this._element);if(o){var s="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(s)))[i.length-1]}var a=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(a),e(this._element).trigger(c),!c.isDefaultPrevented()&&!a.isDefaultPrevented()){r&&(n=document.querySelector(r)),this._activate(this._element,o);var u=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,u):u()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,r=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],s=i&&r&&e(r).hasClass("fade"),a=function(){return o._transitionComplete(t,r,i)};if(r&&s){var c=l.getTransitionDurationFromElement(r);e(r).removeClass("show").one(l.TRANSITION_END,a).emulateTransitionEnd(c)}else a()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),l.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var r=e(t).closest(".dropdown")[0];if(r){var s=[].slice.call(r.querySelectorAll(".dropdown-toggle"));e(s).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),pe._jQueryInterface.call(e(this),"show")})),e.fn.tab=pe._jQueryInterface,e.fn.tab.Constructor=pe,e.fn.tab.noConflict=function(){return e.fn.tab=de,pe._jQueryInterface};var me=e.fn.toast,ge={animation:"boolean",autohide:"boolean",delay:"number"},ve={animation:!0,autohide:!0,delay:500},_e=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),l.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=l.getTransitionDurationFromElement(this._element);e(this._element).one(l.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){clearTimeout(this._timeout),this._timeout=null,this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=s(s(s({},ve),e(this._element).data()),"object"==typeof t&&t?t:{}),l.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=l.getTransitionDurationFromElement(this._element);e(this._element).one(l.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"DefaultType",get:function(){return ge}},{key:"Default",get:function(){return ve}}]),t}();e.fn.toast=_e._jQueryInterface,e.fn.toast.Constructor=_e,e.fn.toast.noConflict=function(){return e.fn.toast=me,_e._jQueryInterface},t.Alert=h,t.Button=d,t.Carousel=y,t.Collapse=S,t.Dropdown=Ft,t.Modal=qt,t.Popover=ae,t.Scrollspy=fe,t.Tab=pe,t.Toast=_e,t.Tooltip=te,t.Util=l,Object.defineProperty(t,"__esModule",{value:!0})}));
|
7 |
//# sourceMappingURL=bootstrap.bundle.min.js.map
|
1 |
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5 |
*/
|
6 |
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery)}(this,(function(t,e){"use strict";function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function o(){return(o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;function r(t){var n=this,i=!1;return e(this).one(s.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||s.triggerTransitionEnd(n)}),t),this}var s={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),r=parseFloat(i);return o||r?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],r=e[i],a=r&&s.isElement(r)?"element":null===(l=r)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(a))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+a+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?s.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};s.jQueryDetection(),e.fn.emulateTransitionEnd=r,e.event.special[s.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var a="alert",l=e.fn[a],c=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=s.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=s.getTransitionDurationFromElement(t);e(t).one(s.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',c._handleDismiss(new c)),e.fn[a]=c._jQueryInterface,e.fn[a].Constructor=c,e.fn[a].noConflict=function(){return e.fn[a]=l,c._jQueryInterface};var h=e.fn.button,u=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var r=i.querySelector(".active");r&&e(r).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();("LABEL"!==i.tagName||o&&"checkbox"!==o.type)&&u._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var r=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;r<s;r++){var a=t[r];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=u._jQueryInterface,e.fn.button.Constructor=u,e.fn.button.noConflict=function(){return e.fn.button=h,u._jQueryInterface};var f="carousel",d=".bs.carousel",p=e.fn[f],m={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},g={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},_={TOUCH:"touch",PEN:"pen"},v=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(s.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(d),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=o({},m,t),s.typeCheckConfig(f,t,g),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&_[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&_[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),r=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(r),r},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,r,a=this,l=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(l),h=n||l&&this._getItemByDirection(t,l),u=this._getItemIndex(h),f=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",r="left"):(i="carousel-item-right",o="carousel-item-prev",r="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,r).isDefaultPrevented()&&l&&h){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(h);var d=e.Event("slid.bs.carousel",{relatedTarget:h,direction:r,from:c,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),s.reflow(h),e(l).addClass(i),e(h).addClass(i);var p=parseInt(h.getAttribute("data-interval"),10);p?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=p):this._config.interval=this._config.defaultInterval||this._config.interval;var m=s.getTransitionDurationFromElement(l);e(l).one(s.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(l).removeClass("active "+o+" "+i),a._isSliding=!1,setTimeout((function(){return e(a._element).trigger(d)}),0)})).emulateTransitionEnd(m)}else e(l).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(d);f&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),r=o({},m,e(this).data());"object"==typeof n&&(r=o({},r,n));var s="string"==typeof n?n:r.slide;if(i||(i=new t(this,r),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof s){if("undefined"==typeof i[s])throw new TypeError('No method named "'+s+'"');i[s]()}else r.interval&&r.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=s.getSelectorFromElement(this);if(i){var r=e(i)[0];if(r&&e(r).hasClass("carousel")){var a=o({},e(r).data(),e(this).data()),l=this.getAttribute("data-slide-to");l&&(a.interval=!1),t._jQueryInterface.call(e(r),a),l&&e(r).data("bs.carousel").to(l),n.preventDefault()}}},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return m}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",v._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);v._jQueryInterface.call(o,o.data())}})),e.fn[f]=v._jQueryInterface,e.fn[f].Constructor=v,e.fn[f].noConflict=function(){return e.fn[f]=p,v._jQueryInterface};var b="collapse",y=e.fn[b],w={toggle:!0,parent:""},E={toggle:"boolean",parent:"(string|element)"},T=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var r=n[i],a=s.getSelectorFromElement(r),l=[].slice.call(document.querySelectorAll(a)).filter((function(e){return e===t}));null!==a&&l.length>0&&(this._selector=a,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var r=e.Event("show.bs.collapse");if(e(this._element).trigger(r),!r.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var a=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[a]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(a[0].toUpperCase()+a.slice(1)),c=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[a]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[a]=this._element[l]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",s.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var r=0;r<o;r++){var a=this._triggerArray[r],l=s.getSelectorFromElement(a);if(null!==l)e([].slice.call(document.querySelectorAll(l))).hasClass("show")||e(a).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var c=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(c)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=o({},w,t)).toggle=Boolean(t.toggle),s.typeCheckConfig(b,t,E),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;s.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',r=[].slice.call(n.querySelectorAll(o));return e(r).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=s.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),r=i.data("bs.collapse"),s=o({},w,i.data(),"object"==typeof n&&n?n:{});if(!r&&s.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(s.toggle=!1),r||(r=new t(this,s),i.data("bs.collapse",r)),"string"==typeof n){if("undefined"==typeof r[n])throw new TypeError('No method named "'+n+'"');r[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return w}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=s.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();T._jQueryInterface.call(t,i)}))})),e.fn[b]=T._jQueryInterface,e.fn[b].Constructor=T,e.fn[b].noConflict=function(){return e.fn[b]=y,T._jQueryInterface};var C="undefined"!=typeof window&&"undefined"!=typeof document&&"undefined"!=typeof navigator,S=function(){for(var t=["Edge","Trident","Firefox"],e=0;e<t.length;e+=1)if(C&&navigator.userAgent.indexOf(t[e])>=0)return 1;return 0}();var D=C&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),S))}};function N(t){return t&&"[object Function]"==={}.toString.call(t)}function k(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function A(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function I(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=k(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:I(A(t))}function O(t){return t&&t.referenceNode?t.referenceNode:t}var x=C&&!(!window.MSInputMethodContext||!document.documentMode),j=C&&/MSIE 10/.test(navigator.userAgent);function L(t){return 11===t?x:10===t?j:x||j}function P(t){if(!t)return document.documentElement;for(var e=L(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===k(n,"position")?P(n):n:t?t.ownerDocument.documentElement:document.documentElement}function F(t){return null!==t.parentNode?F(t.parentNode):t}function R(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var s,a,l=r.commonAncestorContainer;if(t!==l&&e!==l||i.contains(o))return"BODY"===(a=(s=l).nodeName)||"HTML"!==a&&P(s.firstElementChild)!==s?P(l):l;var c=F(t);return c.host?R(c.host,e):R(t,F(e).host)}function H(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top",n="top"===e?"scrollTop":"scrollLeft",i=t.nodeName;if("BODY"===i||"HTML"===i){var o=t.ownerDocument.documentElement,r=t.ownerDocument.scrollingElement||o;return r[n]}return t[n]}function M(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=H(e,"top"),o=H(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function B(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"])+parseFloat(t["border"+i+"Width"])}function q(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],L(10)?parseInt(n["offset"+t])+parseInt(i["margin"+("Height"===t?"Top":"Left")])+parseInt(i["margin"+("Height"===t?"Bottom":"Right")]):0)}function Q(t){var e=t.body,n=t.documentElement,i=L(10)&&getComputedStyle(n);return{height:q("Height",e,n,i),width:q("Width",e,n,i)}}var W=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},U=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),V=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},Y=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function z(t){return Y({},t,{right:t.left+t.width,bottom:t.top+t.height})}function X(t){var e={};try{if(L(10)){e=t.getBoundingClientRect();var n=H(t,"top"),i=H(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}else e=t.getBoundingClientRect()}catch(t){}var o={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},r="HTML"===t.nodeName?Q(t.ownerDocument):{},s=r.width||t.clientWidth||o.width,a=r.height||t.clientHeight||o.height,l=t.offsetWidth-s,c=t.offsetHeight-a;if(l||c){var h=k(t);l-=B(h,"x"),c-=B(h,"y"),o.width-=l,o.height-=c}return z(o)}function K(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=L(10),o="HTML"===e.nodeName,r=X(t),s=X(e),a=I(t),l=k(e),c=parseFloat(l.borderTopWidth),h=parseFloat(l.borderLeftWidth);n&&o&&(s.top=Math.max(s.top,0),s.left=Math.max(s.left,0));var u=z({top:r.top-s.top-c,left:r.left-s.left-h,width:r.width,height:r.height});if(u.marginTop=0,u.marginLeft=0,!i&&o){var f=parseFloat(l.marginTop),d=parseFloat(l.marginLeft);u.top-=c-f,u.bottom-=c-f,u.left-=h-d,u.right-=h-d,u.marginTop=f,u.marginLeft=d}return(i&&!n?e.contains(a):e===a&&"BODY"!==a.nodeName)&&(u=M(u,e)),u}function G(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=K(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),s=e?0:H(n),a=e?0:H(n,"left"),l={top:s-i.top+i.marginTop,left:a-i.left+i.marginLeft,width:o,height:r};return z(l)}function $(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===k(t,"position"))return!0;var n=A(t);return!!n&&$(n)}function J(t){if(!t||!t.parentElement||L())return document.documentElement;for(var e=t.parentElement;e&&"none"===k(e,"transform");)e=e.parentElement;return e||document.documentElement}function Z(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},s=o?J(t):R(t,O(e));if("viewport"===i)r=G(s,o);else{var a=void 0;"scrollParent"===i?"BODY"===(a=I(A(e))).nodeName&&(a=t.ownerDocument.documentElement):a="window"===i?t.ownerDocument.documentElement:i;var l=K(a,s,o);if("HTML"!==a.nodeName||$(s))r=l;else{var c=Q(t.ownerDocument),h=c.height,u=c.width;r.top+=l.top-l.marginTop,r.bottom=h+l.top,r.left+=l.left-l.marginLeft,r.right=u+l.left}}var f="number"==typeof(n=n||0);return r.left+=f?n:n.left||0,r.top+=f?n:n.top||0,r.right-=f?n:n.right||0,r.bottom-=f?n:n.bottom||0,r}function tt(t){return t.width*t.height}function et(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=Z(n,i,r,o),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map((function(t){return Y({key:t},a[t],{area:tt(a[t])})})).sort((function(t,e){return e.area-t.area})),c=l.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),h=c.length>0?c[0].key:l[0].key,u=t.split("-")[1];return h+(u?"-"+u:"")}function nt(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,o=i?J(e):R(e,O(n));return K(n,o,i)}function it(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=parseFloat(e.marginTop||0)+parseFloat(e.marginBottom||0),i=parseFloat(e.marginLeft||0)+parseFloat(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function ot(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function rt(t,e,n){n=n.split("-")[0];var i=it(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),s=r?"top":"left",a=r?"left":"top",l=r?"height":"width",c=r?"width":"height";return o[s]=e[s]+e[l]/2-i[l]/2,o[a]=n===a?e[a]-i[c]:e[ot(a)],o}function st(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function at(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=st(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&N(n)&&(e.offsets.popper=z(e.offsets.popper),e.offsets.reference=z(e.offsets.reference),e=n(e,t))})),e}function lt(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=nt(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=et(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=rt(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=at(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function ct(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ht(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length;i++){var o=e[i],r=o?""+o+n:t;if("undefined"!=typeof document.body.style[r])return r}return null}function ut(){return this.state.isDestroyed=!0,ct(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.position="",this.popper.style.top="",this.popper.style.left="",this.popper.style.right="",this.popper.style.bottom="",this.popper.style.willChange="",this.popper.style[ht("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function ft(t){var e=t.ownerDocument;return e?e.defaultView:window}function dt(t,e,n,i){n.updateBound=i,ft(t).addEventListener("resize",n.updateBound,{passive:!0});var o=I(t);return function t(e,n,i,o){var r="BODY"===e.nodeName,s=r?e.ownerDocument.defaultView:e;s.addEventListener(n,i,{passive:!0}),r||t(I(s.parentNode),n,i,o),o.push(s)}(o,"scroll",n.updateBound,n.scrollParents),n.scrollElement=o,n.eventsEnabled=!0,n}function pt(){this.state.eventsEnabled||(this.state=dt(this.reference,this.options,this.state,this.scheduleUpdate))}function mt(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,ft(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach((function(t){t.removeEventListener("scroll",e.updateBound)})),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function gt(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function _t(t,e){Object.keys(e).forEach((function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&>(e[n])&&(i="px"),t.style[n]=e[n]+i}))}var vt=C&&/Firefox/i.test(navigator.userAgent);function bt(t,e,n){var i=st(t,(function(t){return t.name===e})),o=!!i&&t.some((function(t){return t.name===n&&t.enabled&&t.order<i.order}));if(!o){var r="`"+e+"`",s="`"+n+"`";console.warn(s+" modifier is required by "+r+" modifier in order to work, be sure to include it before "+r+"!")}return o}var yt=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],wt=yt.slice(3);function Et(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=wt.indexOf(t),i=wt.slice(n+1).concat(wt.slice(0,n));return e?i.reverse():i}var Tt="flip",Ct="clockwise",St="counterclockwise";function Dt(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),s=t.split(/(\+|\-)/).map((function(t){return t.trim()})),a=s.indexOf(st(s,(function(t){return-1!==t.search(/,|\s/)})));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map((function(t,i){var o=(1===i?!r:r)?"height":"width",s=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],s=o[2];if(!r)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=i}return z(a)[e]/100*r}if("vh"===s||"vw"===s){return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r}return r}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){gt(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var Nt={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,s=o.popper,a=-1!==["bottom","top"].indexOf(n),l=a?"left":"top",c=a?"width":"height",h={start:V({},l,r[l]),end:V({},l,r[l]+r[c]-s[c])};t.offsets.popper=Y({},s,h[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,o=t.offsets,r=o.popper,s=o.reference,a=i.split("-")[0],l=void 0;return l=gt(+n)?[+n,0]:Dt(n,r,s,a),"left"===a?(r.top+=l[0],r.left-=l[1]):"right"===a?(r.top+=l[0],r.left+=l[1]):"top"===a?(r.left+=l[0],r.top-=l[1]):"bottom"===a&&(r.left+=l[0],r.top+=l[1]),t.popper=r,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||P(t.instance.popper);t.instance.reference===n&&(n=P(n));var i=ht("transform"),o=t.instance.popper.style,r=o.top,s=o.left,a=o[i];o.top="",o.left="",o[i]="";var l=Z(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=s,o[i]=a,e.boundaries=l;var c=e.priority,h=t.offsets.popper,u={primary:function(t){var n=h[t];return h[t]<l[t]&&!e.escapeWithReference&&(n=Math.max(h[t],l[t])),V({},t,n)},secondary:function(t){var n="right"===t?"left":"top",i=h[n];return h[t]>l[t]&&!e.escapeWithReference&&(i=Math.min(h[n],l[t]-("right"===t?h.width:h.height))),V({},n,i)}};return c.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";h=Y({},h,u[e](t))})),t.offsets.popper=h,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]<r(i[l])&&(t.offsets.popper[l]=r(i[l])-n[c]),n[l]>r(i[a])&&(t.offsets.popper[l]=r(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!bt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",h=l?"Top":"Left",u=h.toLowerCase(),f=l?"left":"top",d=l?"bottom":"right",p=it(i)[c];a[d]-p<s[u]&&(t.offsets.popper[u]-=s[u]-(a[d]-p)),a[u]+p>s[d]&&(t.offsets.popper[u]+=a[u]+p-s[d]),t.offsets.popper=z(t.offsets.popper);var m=a[u]+a[c]/2-p/2,g=k(t.instance.popper),_=parseFloat(g["margin"+h]),v=parseFloat(g["border"+h+"Width"]),b=m-t.offsets.popper[u]-_-v;return b=Math.max(Math.min(s[c]-p,b),0),t.arrowElement=i,t.offsets.arrow=(V(n={},u,Math.round(b)),V(n,f,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(ct(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=Z(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=ot(i),r=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case Tt:s=[i,o];break;case Ct:s=Et(i);break;case St:s=Et(i,!0);break;default:s=e.behavior}return s.forEach((function(a,l){if(i!==a||s.length===l+1)return t;i=t.placement.split("-")[0],o=ot(i);var c=t.offsets.popper,h=t.offsets.reference,u=Math.floor,f="left"===i&&u(c.right)>u(h.left)||"right"===i&&u(c.left)<u(h.right)||"top"===i&&u(c.bottom)>u(h.top)||"bottom"===i&&u(c.top)<u(h.bottom),d=u(c.left)<u(n.left),p=u(c.right)>u(n.right),m=u(c.top)<u(n.top),g=u(c.bottom)>u(n.bottom),_="left"===i&&d||"right"===i&&p||"top"===i&&m||"bottom"===i&&g,v=-1!==["top","bottom"].indexOf(i),b=!!e.flipVariations&&(v&&"start"===r&&d||v&&"end"===r&&p||!v&&"start"===r&&m||!v&&"end"===r&&g),y=!!e.flipVariationsByContent&&(v&&"start"===r&&p||v&&"end"===r&&d||!v&&"start"===r&&g||!v&&"end"===r&&m),w=b||y;(f||_||w)&&(t.flipped=!0,(f||_)&&(i=s[l+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=Y({},t.offsets.popper,rt(t.instance.popper,t.offsets.reference,t.placement)),t=at(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return o[s?"left":"top"]=r[n]-(a?o[s?"width":"height"]:0),t.placement=ot(e),t.offsets.popper=z(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!bt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=st(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,o=t.offsets.popper,r=st(t.instance.modifiers,(function(t){return"applyStyle"===t.name})).gpuAcceleration;void 0!==r&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var s=void 0!==r?r:e.gpuAcceleration,a=P(t.instance.popper),l=X(a),c={position:o.position},h=function(t,e){var n=t.offsets,i=n.popper,o=n.reference,r=Math.round,s=Math.floor,a=function(t){return t},l=r(o.width),c=r(i.width),h=-1!==["left","right"].indexOf(t.placement),u=-1!==t.placement.indexOf("-"),f=e?h||u||l%2==c%2?r:s:a,d=e?r:a;return{left:f(l%2==1&&c%2==1&&!u&&e?i.left-1:i.left),top:d(i.top),bottom:d(i.bottom),right:f(i.right)}}(t,window.devicePixelRatio<2||!vt),u="bottom"===n?"top":"bottom",f="right"===i?"left":"right",d=ht("transform"),p=void 0,m=void 0;if(m="bottom"===u?"HTML"===a.nodeName?-a.clientHeight+h.bottom:-l.height+h.bottom:h.top,p="right"===f?"HTML"===a.nodeName?-a.clientWidth+h.right:-l.width+h.right:h.left,s&&d)c[d]="translate3d("+p+"px, "+m+"px, 0)",c[u]=0,c[f]=0,c.willChange="transform";else{var g="bottom"===u?-1:1,_="right"===f?-1:1;c[u]=m*g,c[f]=p*_,c.willChange=u+", "+f}var v={"x-placement":t.placement};return t.attributes=Y({},v,t.attributes),t.styles=Y({},c,t.styles),t.arrowStyles=Y({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){var e,n;return _t(t.instance.popper,t.styles),e=t.instance.popper,n=t.attributes,Object.keys(n).forEach((function(t){!1!==n[t]?e.setAttribute(t,n[t]):e.removeAttribute(t)})),t.arrowElement&&Object.keys(t.arrowStyles).length&&_t(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,o){var r=nt(o,e,t,n.positionFixed),s=et(n.placement,r,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",s),_t(e,{position:n.positionFixed?"fixed":"absolute"}),n},gpuAcceleration:void 0}}},kt=function(){function t(e,n){var i=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};W(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=D(this.update.bind(this)),this.options=Y({},t.Defaults,o),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(Y({},t.Defaults.modifiers,o.modifiers)).forEach((function(e){i.options.modifiers[e]=Y({},t.Defaults.modifiers[e]||{},o.modifiers?o.modifiers[e]:{})})),this.modifiers=Object.keys(this.options.modifiers).map((function(t){return Y({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&N(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var r=this.options.eventsEnabled;r&&this.enableEventListeners(),this.state.eventsEnabled=r}return U(t,[{key:"update",value:function(){return lt.call(this)}},{key:"destroy",value:function(){return ut.call(this)}},{key:"enableEventListeners",value:function(){return pt.call(this)}},{key:"disableEventListeners",value:function(){return mt.call(this)}}]),t}();kt.Utils=("undefined"!=typeof window?window:global).PopperUtils,kt.placements=yt,kt.Defaults=Nt;var At="dropdown",It=e.fn[At],Ot=new RegExp("38|40|27"),xt={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},jt={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},Lt=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var n=t.prototype;return n.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},n.show=function(n){if(void 0===n&&(n=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var i={relatedTarget:this._element},o=e.Event("show.bs.dropdown",i),r=t._getParentFromElement(this._element);if(e(r).trigger(o),!o.isDefaultPrevented()){if(!this._inNavbar&&n){if("undefined"==typeof kt)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var a=this._element;"parent"===this._config.reference?a=r:s.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new kt(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",i))}}},n.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},n.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},n.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},n._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},n._getConfig=function(t){return t=o({},this.constructor.Default,e(this._element).data(),t),s.typeCheckConfig(At,t,this.constructor.DefaultType),t},n._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},n._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},n._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},n._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=o({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},n._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),o({},t,this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,r=i.length;o<r;o++){var s=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(s).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(s,n.target))){var h=e.Event("hide.bs.dropdown",l);e(s).trigger(h),h.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(s).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=s.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!Ot.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var r=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==r.length){var s=r.indexOf(n.target);38===n.which&&s>0&&s--,40===n.which&&s<r.length-1&&s++,s<0&&(s=0),r[s].focus()}}}},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return xt}},{key:"DefaultType",get:function(){return jt}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',Lt._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",Lt._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",Lt._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),Lt._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[At]=Lt._jQueryInterface,e.fn[At].Constructor=Lt,e.fn[At].noConflict=function(){return e.fn[At]=It,Lt._jQueryInterface};var Pt=e.fn.modal,Ft={backdrop:!0,keyboard:!0,focus:!0,show:!0},Rt={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Ht=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var r=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(r)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=o({},Ft,t),s.typeCheckConfig("modal",t,Rt),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;var i=this._element.scrollHeight>document.documentElement.clientHeight;i||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=s.getTransitionDurationFromElement(this._dialog);e(this._element).off(s.TRANSITION_END),e(this._element).one(s.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),i||e(t._element).one(s.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&s.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var r=e.Event("shown.bs.modal",{relatedTarget:t}),a=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(r)};if(i){var l=s.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(s.TRANSITION_END,a).emulateTransitionEnd(l)}else a()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&s.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=s.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(s.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var r=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var a=s.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(s.TRANSITION_END,r).emulateTransitionEnd(a)}else r()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,r=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(r)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,r=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(r)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,r=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(r)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var r=e(this).data("bs.modal"),s=o({},Ft,e(this).data(),"object"==typeof n&&n?n:{});if(r||(r=new t(this,s),e(this).data("bs.modal",r)),"string"==typeof n){if("undefined"==typeof r[n])throw new TypeError('No method named "'+n+'"');r[n](i)}else s.show&&r.show(i)}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return Ft}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,r=s.getSelectorFromElement(this);r&&(n=document.querySelector(r));var a=e(n).data("bs.modal")?"toggle":o({},e(n).data(),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var l=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||l.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));Ht._jQueryInterface.call(e(n),a,this)})),e.fn.modal=Ht._jQueryInterface,e.fn.modal.Constructor=Ht,e.fn.modal.noConflict=function(){return e.fn.modal=Pt,Ht._jQueryInterface};var Mt=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],Bt={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},qt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,Qt=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Wt(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),r=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=r[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[s]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===Mt.indexOf(n)||Boolean(t.nodeValue.match(qt)||t.nodeValue.match(Qt));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,r=i.length;o<r;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=r.length;a<l;a++)s(a);return i.body.innerHTML}var Ut="tooltip",Vt=e.fn[Ut],Yt=new RegExp("(^|\\s)bs-tooltip\\S+","g"),zt=["sanitize","whiteList","sanitizeFn"],Xt={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},Kt={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},Gt={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Bt,popperConfig:null},$t={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Jt=function(){function t(t,e){if("undefined"==typeof kt)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var n=t.prototype;return n.enable=function(){this._isEnabled=!0},n.disable=function(){this._isEnabled=!1},n.toggleEnabled=function(){this._isEnabled=!this._isEnabled},n.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},n.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},n.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var n=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(n);var i=s.findShadowRoot(this.element),o=e.contains(null!==i?i:this.element.ownerDocument.documentElement,this.element);if(n.isDefaultPrevented()||!o)return;var r=this.getTipElement(),a=s.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&e(r).addClass("fade");var l="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,c=this._getAttachment(l);this.addAttachmentClass(c);var h=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(h),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new kt(this.element,r,this._getPopperConfig(c)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var u=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=s.getTransitionDurationFromElement(this.tip);e(this.tip).one(s.TRANSITION_END,u).emulateTransitionEnd(f)}else u()}},n.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),r=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var a=s.getTransitionDurationFromElement(i);e(i).one(s.TRANSITION_END,r).emulateTransitionEnd(a)}else r();this._hoverState=""}},n.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},n.isWithContent=function(){return Boolean(this.getTitle())},n.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},n.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},n.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},n.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Wt(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},n.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},n._getPopperConfig=function(t){var e=this;return o({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},n._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=o({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},n._getContainer=function(){return!1===this.config.container?document.body:s.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},n._getAttachment=function(t){return Kt[t.toUpperCase()]},n._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=o({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},n._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},n._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},n._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},n._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},n._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==zt.indexOf(t)&&delete n[t]})),"number"==typeof(t=o({},this.constructor.Default,n,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),s.typeCheckConfig(Ut,t,this.constructor.DefaultType),t.sanitize&&(t.template=Wt(t.template,t.whiteList,t.sanitizeFn)),t},n._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},n._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(Yt);null!==n&&n.length&&t.removeClass(n.join(""))},n._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},n._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return Gt}},{key:"NAME",get:function(){return Ut}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return $t}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Xt}}]),t}();e.fn[Ut]=Jt._jQueryInterface,e.fn[Ut].Constructor=Jt,e.fn[Ut].noConflict=function(){return e.fn[Ut]=Vt,Jt._jQueryInterface};var Zt="popover",te=e.fn[Zt],ee=new RegExp("(^|\\s)bs-popover\\S+","g"),ne=o({},Jt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),ie=o({},Jt.DefaultType,{content:"(string|element|function)"}),oe={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},re=function(t){var n,o;function r(){return t.apply(this,arguments)||this}o=t,(n=r).prototype=Object.create(o.prototype),n.prototype.constructor=n,n.__proto__=o;var s=r.prototype;return s.isWithContent=function(){return this.getTitle()||this._getContent()},s.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},s.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},s.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},s._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},s._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(ee);null!==n&&n.length>0&&t.removeClass(n.join(""))},r._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new r(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},i(r,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return ne}},{key:"NAME",get:function(){return Zt}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return oe}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return ie}}]),r}(Jt);e.fn[Zt]=re._jQueryInterface,e.fn[Zt].Constructor=re,e.fn[Zt].noConflict=function(){return e.fn[Zt]=te,re._jQueryInterface};var se="scrollspy",ae=e.fn[se],le={offset:10,method:"auto",target:""},ce={offset:"number",method:"string",target:"(string|element)"},he=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,r=s.getSelectorFromElement(t);if(r&&(n=document.querySelector(r)),n){var a=n.getBoundingClientRect();if(a.width||a.height)return[e(n)[i]().top+o,r]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=o({},le,"object"==typeof t&&t?t:{})).target&&s.isElement(t.target)){var n=e(t.target).attr("id");n||(n=s.getUID(se),e(t.target).attr("id",n)),t.target="#"+n}return s.typeCheckConfig(se,t,ce),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return le}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);he._jQueryInterface.call(i,i.data())}})),e.fn[se]=he._jQueryInterface,e.fn[se].Constructor=he,e.fn[se].noConflict=function(){return e.fn[se]=ae,he._jQueryInterface};var ue=e.fn.tab,fe=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],r=s.getSelectorFromElement(this._element);if(o){var a="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(a)))[i.length-1]}var l=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(l),e(this._element).trigger(c),!c.isDefaultPrevented()&&!l.isDefaultPrevented()){r&&(n=document.querySelector(r)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,r=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],a=i&&r&&e(r).hasClass("fade"),l=function(){return o._transitionComplete(t,r,i)};if(r&&a){var c=s.getTransitionDurationFromElement(r);e(r).removeClass("show").one(s.TRANSITION_END,l).emulateTransitionEnd(c)}else l()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),s.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var r=e(t).closest(".dropdown")[0];if(r){var a=[].slice.call(r.querySelectorAll(".dropdown-toggle"));e(a).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),fe._jQueryInterface.call(e(this),"show")})),e.fn.tab=fe._jQueryInterface,e.fn.tab.Constructor=fe,e.fn.tab.noConflict=function(){return e.fn.tab=ue,fe._jQueryInterface};var de=e.fn.toast,pe={animation:"boolean",autohide:"boolean",delay:"number"},me={animation:!0,autohide:!0,delay:500},ge=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),s.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=o({},me,e(this._element).data(),"object"==typeof t&&t?t:{}),s.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=s.getTransitionDurationFromElement(this._element);e(this._element).one(s.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},n._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},i(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"DefaultType",get:function(){return pe}},{key:"Default",get:function(){return me}}]),t}();e.fn.toast=ge._jQueryInterface,e.fn.toast.Constructor=ge,e.fn.toast.noConflict=function(){return e.fn.toast=de,ge._jQueryInterface},t.Alert=c,t.Button=u,t.Carousel=v,t.Collapse=T,t.Dropdown=Lt,t.Modal=Ht,t.Popover=re,t.Scrollspy=he,t.Tab=fe,t.Toast=ge,t.Tooltip=Jt,t.Util=s,Object.defineProperty(t,"__esModule",{value:!0})}));
|
7 |
//# sourceMappingURL=bootstrap.bundle.min.js.map
|
resources/js/bootstrap4.js
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
/*!
|
2 |
-
* Bootstrap v4.5.
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
5 |
*/
|
6 |
(function (global, factory) {
|
7 |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) :
|
8 |
typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) :
|
9 |
-
(global = global || self, factory(global.bootstrap = {}, global.jQuery, global.Popper));
|
10 |
}(this, (function (exports, $, Popper) { 'use strict';
|
11 |
|
12 |
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
|
@@ -28,53 +28,22 @@
|
|
28 |
return Constructor;
|
29 |
}
|
30 |
|
31 |
-
function
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
enumerable: true,
|
36 |
-
configurable: true,
|
37 |
-
writable: true
|
38 |
-
});
|
39 |
-
} else {
|
40 |
-
obj[key] = value;
|
41 |
-
}
|
42 |
-
|
43 |
-
return obj;
|
44 |
-
}
|
45 |
-
|
46 |
-
function ownKeys(object, enumerableOnly) {
|
47 |
-
var keys = Object.keys(object);
|
48 |
-
|
49 |
-
if (Object.getOwnPropertySymbols) {
|
50 |
-
var symbols = Object.getOwnPropertySymbols(object);
|
51 |
-
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
52 |
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
53 |
-
});
|
54 |
-
keys.push.apply(keys, symbols);
|
55 |
-
}
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
var source = arguments[i] != null ? arguments[i] : {};
|
63 |
-
|
64 |
-
if (i % 2) {
|
65 |
-
ownKeys(Object(source), true).forEach(function (key) {
|
66 |
-
_defineProperty(target, key, source[key]);
|
67 |
-
});
|
68 |
-
} else if (Object.getOwnPropertyDescriptors) {
|
69 |
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
70 |
-
} else {
|
71 |
-
ownKeys(Object(source)).forEach(function (key) {
|
72 |
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
73 |
-
});
|
74 |
}
|
75 |
-
}
|
76 |
|
77 |
-
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
function _inheritsLoose(subClass, superClass) {
|
@@ -85,8 +54,8 @@
|
|
85 |
|
86 |
/**
|
87 |
* --------------------------------------------------------------------------
|
88 |
-
* Bootstrap (v4.5.
|
89 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
90 |
* --------------------------------------------------------------------------
|
91 |
*/
|
92 |
/**
|
@@ -266,7 +235,7 @@
|
|
266 |
*/
|
267 |
|
268 |
var NAME = 'alert';
|
269 |
-
var VERSION = '4.5.
|
270 |
var DATA_KEY = 'bs.alert';
|
271 |
var EVENT_KEY = "." + DATA_KEY;
|
272 |
var DATA_API_KEY = '.data-api';
|
@@ -422,7 +391,7 @@
|
|
422 |
*/
|
423 |
|
424 |
var NAME$1 = 'button';
|
425 |
-
var VERSION$1 = '4.5.
|
426 |
var DATA_KEY$1 = 'bs.button';
|
427 |
var EVENT_KEY$1 = "." + DATA_KEY$1;
|
428 |
var DATA_API_KEY$1 = '.data-api';
|
@@ -557,11 +526,9 @@
|
|
557 |
return;
|
558 |
}
|
559 |
|
560 |
-
if (initialButton.tagName
|
561 |
-
|
562 |
}
|
563 |
-
|
564 |
-
Button._jQueryInterface.call($(button), 'toggle');
|
565 |
}
|
566 |
}).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
|
567 |
var button = $(event.target).closest(SELECTOR_BUTTON)[0];
|
@@ -617,7 +584,7 @@
|
|
617 |
*/
|
618 |
|
619 |
var NAME$2 = 'carousel';
|
620 |
-
var VERSION$2 = '4.5.
|
621 |
var DATA_KEY$2 = 'bs.carousel';
|
622 |
var EVENT_KEY$2 = "." + DATA_KEY$2;
|
623 |
var DATA_API_KEY$2 = '.data-api';
|
@@ -804,7 +771,7 @@
|
|
804 |
;
|
805 |
|
806 |
_proto._getConfig = function _getConfig(config) {
|
807 |
-
config =
|
808 |
Util.typeCheckConfig(NAME$2, config, DefaultType);
|
809 |
return config;
|
810 |
};
|
@@ -1094,10 +1061,10 @@
|
|
1094 |
return this.each(function () {
|
1095 |
var data = $(this).data(DATA_KEY$2);
|
1096 |
|
1097 |
-
var _config =
|
1098 |
|
1099 |
if (typeof config === 'object') {
|
1100 |
-
_config =
|
1101 |
}
|
1102 |
|
1103 |
var action = typeof config === 'string' ? config : _config.slide;
|
@@ -1135,7 +1102,7 @@
|
|
1135 |
return;
|
1136 |
}
|
1137 |
|
1138 |
-
var config =
|
1139 |
|
1140 |
var slideIndex = this.getAttribute('data-slide-to');
|
1141 |
|
@@ -1204,7 +1171,7 @@
|
|
1204 |
*/
|
1205 |
|
1206 |
var NAME$3 = 'collapse';
|
1207 |
-
var VERSION$3 = '4.5.
|
1208 |
var DATA_KEY$3 = 'bs.collapse';
|
1209 |
var EVENT_KEY$3 = "." + DATA_KEY$3;
|
1210 |
var DATA_API_KEY$3 = '.data-api';
|
@@ -1419,7 +1386,7 @@
|
|
1419 |
;
|
1420 |
|
1421 |
_proto._getConfig = function _getConfig(config) {
|
1422 |
-
config =
|
1423 |
config.toggle = Boolean(config.toggle); // Coerce string values
|
1424 |
|
1425 |
Util.typeCheckConfig(NAME$3, config, DefaultType$1);
|
@@ -1473,7 +1440,7 @@
|
|
1473 |
var $this = $(this);
|
1474 |
var data = $this.data(DATA_KEY$3);
|
1475 |
|
1476 |
-
var _config =
|
1477 |
|
1478 |
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
|
1479 |
_config.toggle = false;
|
@@ -1553,7 +1520,7 @@
|
|
1553 |
*/
|
1554 |
|
1555 |
var NAME$4 = 'dropdown';
|
1556 |
-
var VERSION$4 = '4.5.
|
1557 |
var DATA_KEY$4 = 'bs.dropdown';
|
1558 |
var EVENT_KEY$4 = "." + DATA_KEY$4;
|
1559 |
var DATA_API_KEY$4 = '.data-api';
|
@@ -1780,7 +1747,7 @@
|
|
1780 |
};
|
1781 |
|
1782 |
_proto._getConfig = function _getConfig(config) {
|
1783 |
-
config =
|
1784 |
Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
|
1785 |
return config;
|
1786 |
};
|
@@ -1825,7 +1792,7 @@
|
|
1825 |
|
1826 |
if (typeof this._config.offset === 'function') {
|
1827 |
offset.fn = function (data) {
|
1828 |
-
data.offsets =
|
1829 |
return data;
|
1830 |
};
|
1831 |
} else {
|
@@ -1855,7 +1822,7 @@
|
|
1855 |
};
|
1856 |
}
|
1857 |
|
1858 |
-
return
|
1859 |
} // Static
|
1860 |
;
|
1861 |
|
@@ -2067,7 +2034,7 @@
|
|
2067 |
*/
|
2068 |
|
2069 |
var NAME$5 = 'modal';
|
2070 |
-
var VERSION$5 = '4.5.
|
2071 |
var DATA_KEY$5 = 'bs.modal';
|
2072 |
var EVENT_KEY$5 = "." + DATA_KEY$5;
|
2073 |
var DATA_API_KEY$5 = '.data-api';
|
@@ -2259,7 +2226,7 @@
|
|
2259 |
;
|
2260 |
|
2261 |
_proto._getConfig = function _getConfig(config) {
|
2262 |
-
config =
|
2263 |
Util.typeCheckConfig(NAME$5, config, DefaultType$3);
|
2264 |
return config;
|
2265 |
};
|
@@ -2275,11 +2242,24 @@
|
|
2275 |
return;
|
2276 |
}
|
2277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
2278 |
this._element.classList.add(CLASS_NAME_STATIC);
|
2279 |
|
2280 |
-
var modalTransitionDuration = Util.getTransitionDurationFromElement(this.
|
|
|
2281 |
$(this._element).one(Util.TRANSITION_END, function () {
|
2282 |
_this3._element.classList.remove(CLASS_NAME_STATIC);
|
|
|
|
|
|
|
|
|
|
|
|
|
2283 |
}).emulateTransitionEnd(modalTransitionDuration);
|
2284 |
|
2285 |
this._element.focus();
|
@@ -2305,6 +2285,8 @@
|
|
2305 |
|
2306 |
this._element.setAttribute('aria-modal', true);
|
2307 |
|
|
|
|
|
2308 |
if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
|
2309 |
modalBody.scrollTop = 0;
|
2310 |
} else {
|
@@ -2392,6 +2374,8 @@
|
|
2392 |
|
2393 |
this._element.removeAttribute('aria-modal');
|
2394 |
|
|
|
|
|
2395 |
this._isTransitioning = false;
|
2396 |
|
2397 |
this._showBackdrop(function () {
|
@@ -2573,7 +2557,7 @@
|
|
2573 |
return this.each(function () {
|
2574 |
var data = $(this).data(DATA_KEY$5);
|
2575 |
|
2576 |
-
var _config =
|
2577 |
|
2578 |
if (!data) {
|
2579 |
data = new Modal(this, _config);
|
@@ -2623,7 +2607,7 @@
|
|
2623 |
target = document.querySelector(selector);
|
2624 |
}
|
2625 |
|
2626 |
-
var config = $(target).data(DATA_KEY$5) ? 'toggle' :
|
2627 |
|
2628 |
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
2629 |
event.preventDefault();
|
@@ -2660,8 +2644,8 @@
|
|
2660 |
|
2661 |
/**
|
2662 |
* --------------------------------------------------------------------------
|
2663 |
-
* Bootstrap (v4.5.
|
2664 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
2665 |
* --------------------------------------------------------------------------
|
2666 |
*/
|
2667 |
var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
|
@@ -2786,7 +2770,7 @@
|
|
2786 |
*/
|
2787 |
|
2788 |
var NAME$6 = 'tooltip';
|
2789 |
-
var VERSION$6 = '4.5.
|
2790 |
var DATA_KEY$6 = 'bs.tooltip';
|
2791 |
var EVENT_KEY$6 = "." + DATA_KEY$6;
|
2792 |
var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
|
@@ -3174,7 +3158,7 @@
|
|
3174 |
return _this3._handlePopperPlacementChange(data);
|
3175 |
}
|
3176 |
};
|
3177 |
-
return
|
3178 |
};
|
3179 |
|
3180 |
_proto._getOffset = function _getOffset() {
|
@@ -3184,7 +3168,7 @@
|
|
3184 |
|
3185 |
if (typeof this.config.offset === 'function') {
|
3186 |
offset.fn = function (data) {
|
3187 |
-
data.offsets =
|
3188 |
return data;
|
3189 |
};
|
3190 |
} else {
|
@@ -3239,7 +3223,7 @@
|
|
3239 |
$(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
|
3240 |
|
3241 |
if (this.config.selector) {
|
3242 |
-
this.config =
|
3243 |
trigger: 'manual',
|
3244 |
selector: ''
|
3245 |
});
|
@@ -3339,7 +3323,7 @@
|
|
3339 |
delete dataAttributes[dataAttr];
|
3340 |
}
|
3341 |
});
|
3342 |
-
config =
|
3343 |
|
3344 |
if (typeof config.delay === 'number') {
|
3345 |
config.delay = {
|
@@ -3498,21 +3482,21 @@
|
|
3498 |
*/
|
3499 |
|
3500 |
var NAME$7 = 'popover';
|
3501 |
-
var VERSION$7 = '4.5.
|
3502 |
var DATA_KEY$7 = 'bs.popover';
|
3503 |
var EVENT_KEY$7 = "." + DATA_KEY$7;
|
3504 |
var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
|
3505 |
var CLASS_PREFIX$1 = 'bs-popover';
|
3506 |
var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
|
3507 |
|
3508 |
-
var Default$5 =
|
3509 |
placement: 'right',
|
3510 |
trigger: 'click',
|
3511 |
content: '',
|
3512 |
template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
|
3513 |
});
|
3514 |
|
3515 |
-
var DefaultType$5 =
|
3516 |
content: '(string|element|function)'
|
3517 |
});
|
3518 |
|
@@ -3678,7 +3662,7 @@
|
|
3678 |
*/
|
3679 |
|
3680 |
var NAME$8 = 'scrollspy';
|
3681 |
-
var VERSION$8 = '4.5.
|
3682 |
var DATA_KEY$8 = 'bs.scrollspy';
|
3683 |
var EVENT_KEY$8 = "." + DATA_KEY$8;
|
3684 |
var DATA_API_KEY$6 = '.data-api';
|
@@ -3792,7 +3776,7 @@
|
|
3792 |
;
|
3793 |
|
3794 |
_proto._getConfig = function _getConfig(config) {
|
3795 |
-
config =
|
3796 |
|
3797 |
if (typeof config.target !== 'string' && Util.isElement(config.target)) {
|
3798 |
var id = $(config.target).attr('id');
|
@@ -3970,7 +3954,7 @@
|
|
3970 |
*/
|
3971 |
|
3972 |
var NAME$9 = 'tab';
|
3973 |
-
var VERSION$9 = '4.5.
|
3974 |
var DATA_KEY$9 = 'bs.tab';
|
3975 |
var EVENT_KEY$9 = "." + DATA_KEY$9;
|
3976 |
var DATA_API_KEY$7 = '.data-api';
|
@@ -4196,7 +4180,7 @@
|
|
4196 |
*/
|
4197 |
|
4198 |
var NAME$a = 'toast';
|
4199 |
-
var VERSION$a = '4.5.
|
4200 |
var DATA_KEY$a = 'bs.toast';
|
4201 |
var EVENT_KEY$a = "." + DATA_KEY$a;
|
4202 |
var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
|
@@ -4249,6 +4233,8 @@
|
|
4249 |
return;
|
4250 |
}
|
4251 |
|
|
|
|
|
4252 |
if (this._config.animation) {
|
4253 |
this._element.classList.add(CLASS_NAME_FADE$5);
|
4254 |
}
|
@@ -4297,8 +4283,7 @@
|
|
4297 |
};
|
4298 |
|
4299 |
_proto.dispose = function dispose() {
|
4300 |
-
|
4301 |
-
this._timeout = null;
|
4302 |
|
4303 |
if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
|
4304 |
this._element.classList.remove(CLASS_NAME_SHOW$7);
|
@@ -4312,7 +4297,7 @@
|
|
4312 |
;
|
4313 |
|
4314 |
_proto._getConfig = function _getConfig(config) {
|
4315 |
-
config =
|
4316 |
Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
|
4317 |
return config;
|
4318 |
};
|
@@ -4342,6 +4327,11 @@
|
|
4342 |
} else {
|
4343 |
complete();
|
4344 |
}
|
|
|
|
|
|
|
|
|
|
|
4345 |
} // Static
|
4346 |
;
|
4347 |
|
1 |
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5 |
*/
|
6 |
(function (global, factory) {
|
7 |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) :
|
8 |
typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) :
|
9 |
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bootstrap = {}, global.jQuery, global.Popper));
|
10 |
}(this, (function (exports, $, Popper) { 'use strict';
|
11 |
|
12 |
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
|
28 |
return Constructor;
|
29 |
}
|
30 |
|
31 |
+
function _extends() {
|
32 |
+
_extends = Object.assign || function (target) {
|
33 |
+
for (var i = 1; i < arguments.length; i++) {
|
34 |
+
var source = arguments[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
+
for (var key in source) {
|
37 |
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
38 |
+
target[key] = source[key];
|
39 |
+
}
|
40 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
|
|
42 |
|
43 |
+
return target;
|
44 |
+
};
|
45 |
+
|
46 |
+
return _extends.apply(this, arguments);
|
47 |
}
|
48 |
|
49 |
function _inheritsLoose(subClass, superClass) {
|
54 |
|
55 |
/**
|
56 |
* --------------------------------------------------------------------------
|
57 |
+
* Bootstrap (v4.5.2): util.js
|
58 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
59 |
* --------------------------------------------------------------------------
|
60 |
*/
|
61 |
/**
|
235 |
*/
|
236 |
|
237 |
var NAME = 'alert';
|
238 |
+
var VERSION = '4.5.2';
|
239 |
var DATA_KEY = 'bs.alert';
|
240 |
var EVENT_KEY = "." + DATA_KEY;
|
241 |
var DATA_API_KEY = '.data-api';
|
391 |
*/
|
392 |
|
393 |
var NAME$1 = 'button';
|
394 |
+
var VERSION$1 = '4.5.2';
|
395 |
var DATA_KEY$1 = 'bs.button';
|
396 |
var EVENT_KEY$1 = "." + DATA_KEY$1;
|
397 |
var DATA_API_KEY$1 = '.data-api';
|
526 |
return;
|
527 |
}
|
528 |
|
529 |
+
if (initialButton.tagName !== 'LABEL' || inputBtn && inputBtn.type !== 'checkbox') {
|
530 |
+
Button._jQueryInterface.call($(button), 'toggle');
|
531 |
}
|
|
|
|
|
532 |
}
|
533 |
}).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
|
534 |
var button = $(event.target).closest(SELECTOR_BUTTON)[0];
|
584 |
*/
|
585 |
|
586 |
var NAME$2 = 'carousel';
|
587 |
+
var VERSION$2 = '4.5.2';
|
588 |
var DATA_KEY$2 = 'bs.carousel';
|
589 |
var EVENT_KEY$2 = "." + DATA_KEY$2;
|
590 |
var DATA_API_KEY$2 = '.data-api';
|
771 |
;
|
772 |
|
773 |
_proto._getConfig = function _getConfig(config) {
|
774 |
+
config = _extends({}, Default, config);
|
775 |
Util.typeCheckConfig(NAME$2, config, DefaultType);
|
776 |
return config;
|
777 |
};
|
1061 |
return this.each(function () {
|
1062 |
var data = $(this).data(DATA_KEY$2);
|
1063 |
|
1064 |
+
var _config = _extends({}, Default, $(this).data());
|
1065 |
|
1066 |
if (typeof config === 'object') {
|
1067 |
+
_config = _extends({}, _config, config);
|
1068 |
}
|
1069 |
|
1070 |
var action = typeof config === 'string' ? config : _config.slide;
|
1102 |
return;
|
1103 |
}
|
1104 |
|
1105 |
+
var config = _extends({}, $(target).data(), $(this).data());
|
1106 |
|
1107 |
var slideIndex = this.getAttribute('data-slide-to');
|
1108 |
|
1171 |
*/
|
1172 |
|
1173 |
var NAME$3 = 'collapse';
|
1174 |
+
var VERSION$3 = '4.5.2';
|
1175 |
var DATA_KEY$3 = 'bs.collapse';
|
1176 |
var EVENT_KEY$3 = "." + DATA_KEY$3;
|
1177 |
var DATA_API_KEY$3 = '.data-api';
|
1386 |
;
|
1387 |
|
1388 |
_proto._getConfig = function _getConfig(config) {
|
1389 |
+
config = _extends({}, Default$1, config);
|
1390 |
config.toggle = Boolean(config.toggle); // Coerce string values
|
1391 |
|
1392 |
Util.typeCheckConfig(NAME$3, config, DefaultType$1);
|
1440 |
var $this = $(this);
|
1441 |
var data = $this.data(DATA_KEY$3);
|
1442 |
|
1443 |
+
var _config = _extends({}, Default$1, $this.data(), typeof config === 'object' && config ? config : {});
|
1444 |
|
1445 |
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
|
1446 |
_config.toggle = false;
|
1520 |
*/
|
1521 |
|
1522 |
var NAME$4 = 'dropdown';
|
1523 |
+
var VERSION$4 = '4.5.2';
|
1524 |
var DATA_KEY$4 = 'bs.dropdown';
|
1525 |
var EVENT_KEY$4 = "." + DATA_KEY$4;
|
1526 |
var DATA_API_KEY$4 = '.data-api';
|
1747 |
};
|
1748 |
|
1749 |
_proto._getConfig = function _getConfig(config) {
|
1750 |
+
config = _extends({}, this.constructor.Default, $(this._element).data(), config);
|
1751 |
Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
|
1752 |
return config;
|
1753 |
};
|
1792 |
|
1793 |
if (typeof this._config.offset === 'function') {
|
1794 |
offset.fn = function (data) {
|
1795 |
+
data.offsets = _extends({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {});
|
1796 |
return data;
|
1797 |
};
|
1798 |
} else {
|
1822 |
};
|
1823 |
}
|
1824 |
|
1825 |
+
return _extends({}, popperConfig, this._config.popperConfig);
|
1826 |
} // Static
|
1827 |
;
|
1828 |
|
2034 |
*/
|
2035 |
|
2036 |
var NAME$5 = 'modal';
|
2037 |
+
var VERSION$5 = '4.5.2';
|
2038 |
var DATA_KEY$5 = 'bs.modal';
|
2039 |
var EVENT_KEY$5 = "." + DATA_KEY$5;
|
2040 |
var DATA_API_KEY$5 = '.data-api';
|
2226 |
;
|
2227 |
|
2228 |
_proto._getConfig = function _getConfig(config) {
|
2229 |
+
config = _extends({}, Default$3, config);
|
2230 |
Util.typeCheckConfig(NAME$5, config, DefaultType$3);
|
2231 |
return config;
|
2232 |
};
|
2242 |
return;
|
2243 |
}
|
2244 |
|
2245 |
+
var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
2246 |
+
|
2247 |
+
if (!isModalOverflowing) {
|
2248 |
+
this._element.style.overflowY = 'hidden';
|
2249 |
+
}
|
2250 |
+
|
2251 |
this._element.classList.add(CLASS_NAME_STATIC);
|
2252 |
|
2253 |
+
var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog);
|
2254 |
+
$(this._element).off(Util.TRANSITION_END);
|
2255 |
$(this._element).one(Util.TRANSITION_END, function () {
|
2256 |
_this3._element.classList.remove(CLASS_NAME_STATIC);
|
2257 |
+
|
2258 |
+
if (!isModalOverflowing) {
|
2259 |
+
$(_this3._element).one(Util.TRANSITION_END, function () {
|
2260 |
+
_this3._element.style.overflowY = '';
|
2261 |
+
}).emulateTransitionEnd(_this3._element, modalTransitionDuration);
|
2262 |
+
}
|
2263 |
}).emulateTransitionEnd(modalTransitionDuration);
|
2264 |
|
2265 |
this._element.focus();
|
2285 |
|
2286 |
this._element.setAttribute('aria-modal', true);
|
2287 |
|
2288 |
+
this._element.setAttribute('role', 'dialog');
|
2289 |
+
|
2290 |
if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
|
2291 |
modalBody.scrollTop = 0;
|
2292 |
} else {
|
2374 |
|
2375 |
this._element.removeAttribute('aria-modal');
|
2376 |
|
2377 |
+
this._element.removeAttribute('role');
|
2378 |
+
|
2379 |
this._isTransitioning = false;
|
2380 |
|
2381 |
this._showBackdrop(function () {
|
2557 |
return this.each(function () {
|
2558 |
var data = $(this).data(DATA_KEY$5);
|
2559 |
|
2560 |
+
var _config = _extends({}, Default$3, $(this).data(), typeof config === 'object' && config ? config : {});
|
2561 |
|
2562 |
if (!data) {
|
2563 |
data = new Modal(this, _config);
|
2607 |
target = document.querySelector(selector);
|
2608 |
}
|
2609 |
|
2610 |
+
var config = $(target).data(DATA_KEY$5) ? 'toggle' : _extends({}, $(target).data(), $(this).data());
|
2611 |
|
2612 |
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
2613 |
event.preventDefault();
|
2644 |
|
2645 |
/**
|
2646 |
* --------------------------------------------------------------------------
|
2647 |
+
* Bootstrap (v4.5.2): tools/sanitizer.js
|
2648 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
2649 |
* --------------------------------------------------------------------------
|
2650 |
*/
|
2651 |
var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
|
2770 |
*/
|
2771 |
|
2772 |
var NAME$6 = 'tooltip';
|
2773 |
+
var VERSION$6 = '4.5.2';
|
2774 |
var DATA_KEY$6 = 'bs.tooltip';
|
2775 |
var EVENT_KEY$6 = "." + DATA_KEY$6;
|
2776 |
var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
|
3158 |
return _this3._handlePopperPlacementChange(data);
|
3159 |
}
|
3160 |
};
|
3161 |
+
return _extends({}, defaultBsConfig, this.config.popperConfig);
|
3162 |
};
|
3163 |
|
3164 |
_proto._getOffset = function _getOffset() {
|
3168 |
|
3169 |
if (typeof this.config.offset === 'function') {
|
3170 |
offset.fn = function (data) {
|
3171 |
+
data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element) || {});
|
3172 |
return data;
|
3173 |
};
|
3174 |
} else {
|
3223 |
$(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
|
3224 |
|
3225 |
if (this.config.selector) {
|
3226 |
+
this.config = _extends({}, this.config, {
|
3227 |
trigger: 'manual',
|
3228 |
selector: ''
|
3229 |
});
|
3323 |
delete dataAttributes[dataAttr];
|
3324 |
}
|
3325 |
});
|
3326 |
+
config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
|
3327 |
|
3328 |
if (typeof config.delay === 'number') {
|
3329 |
config.delay = {
|
3482 |
*/
|
3483 |
|
3484 |
var NAME$7 = 'popover';
|
3485 |
+
var VERSION$7 = '4.5.2';
|
3486 |
var DATA_KEY$7 = 'bs.popover';
|
3487 |
var EVENT_KEY$7 = "." + DATA_KEY$7;
|
3488 |
var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
|
3489 |
var CLASS_PREFIX$1 = 'bs-popover';
|
3490 |
var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
|
3491 |
|
3492 |
+
var Default$5 = _extends({}, Tooltip.Default, {
|
3493 |
placement: 'right',
|
3494 |
trigger: 'click',
|
3495 |
content: '',
|
3496 |
template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
|
3497 |
});
|
3498 |
|
3499 |
+
var DefaultType$5 = _extends({}, Tooltip.DefaultType, {
|
3500 |
content: '(string|element|function)'
|
3501 |
});
|
3502 |
|
3662 |
*/
|
3663 |
|
3664 |
var NAME$8 = 'scrollspy';
|
3665 |
+
var VERSION$8 = '4.5.2';
|
3666 |
var DATA_KEY$8 = 'bs.scrollspy';
|
3667 |
var EVENT_KEY$8 = "." + DATA_KEY$8;
|
3668 |
var DATA_API_KEY$6 = '.data-api';
|
3776 |
;
|
3777 |
|
3778 |
_proto._getConfig = function _getConfig(config) {
|
3779 |
+
config = _extends({}, Default$6, typeof config === 'object' && config ? config : {});
|
3780 |
|
3781 |
if (typeof config.target !== 'string' && Util.isElement(config.target)) {
|
3782 |
var id = $(config.target).attr('id');
|
3954 |
*/
|
3955 |
|
3956 |
var NAME$9 = 'tab';
|
3957 |
+
var VERSION$9 = '4.5.2';
|
3958 |
var DATA_KEY$9 = 'bs.tab';
|
3959 |
var EVENT_KEY$9 = "." + DATA_KEY$9;
|
3960 |
var DATA_API_KEY$7 = '.data-api';
|
4180 |
*/
|
4181 |
|
4182 |
var NAME$a = 'toast';
|
4183 |
+
var VERSION$a = '4.5.2';
|
4184 |
var DATA_KEY$a = 'bs.toast';
|
4185 |
var EVENT_KEY$a = "." + DATA_KEY$a;
|
4186 |
var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
|
4233 |
return;
|
4234 |
}
|
4235 |
|
4236 |
+
this._clearTimeout();
|
4237 |
+
|
4238 |
if (this._config.animation) {
|
4239 |
this._element.classList.add(CLASS_NAME_FADE$5);
|
4240 |
}
|
4283 |
};
|
4284 |
|
4285 |
_proto.dispose = function dispose() {
|
4286 |
+
this._clearTimeout();
|
|
|
4287 |
|
4288 |
if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
|
4289 |
this._element.classList.remove(CLASS_NAME_SHOW$7);
|
4297 |
;
|
4298 |
|
4299 |
_proto._getConfig = function _getConfig(config) {
|
4300 |
+
config = _extends({}, Default$7, $(this._element).data(), typeof config === 'object' && config ? config : {});
|
4301 |
Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
|
4302 |
return config;
|
4303 |
};
|
4327 |
} else {
|
4328 |
complete();
|
4329 |
}
|
4330 |
+
};
|
4331 |
+
|
4332 |
+
_proto._clearTimeout = function _clearTimeout() {
|
4333 |
+
clearTimeout(this._timeout);
|
4334 |
+
this._timeout = null;
|
4335 |
} // Static
|
4336 |
;
|
4337 |
|
resources/js/bootstrap4.min.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
/*!
|
2 |
-
* Bootstrap v4.5.
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
5 |
*/
|
6 |
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t=t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}function s(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function r(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function a(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?r(Object(n),!0).forEach((function(e){s(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e,n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n;function l(t){var n=this,i=!1;return e(this).one(c.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||c.triggerTransitionEnd(n)}),t),this}var c={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),s=parseFloat(i);return o||s?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],s=e[i],r=s&&c.isElement(s)?"element":null===(a=s)||"undefined"==typeof a?""+a:{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+r+'" but expected type "'+o+'".')}var a},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};c.jQueryDetection(),e.fn.emulateTransitionEnd=l,e.event.special[c.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var h="alert",u=e.fn[h],d=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=c.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=c.getTransitionDurationFromElement(t);e(t).one(c.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',d._handleDismiss(new d)),e.fn[h]=d._jQueryInterface,e.fn[h].Constructor=d,e.fn[h].noConflict=function(){return e.fn[h]=u,d._jQueryInterface};var f=e.fn.button,g=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var s=i.querySelector(".active");s&&e(s).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();"LABEL"===i.tagName&&o&&"checkbox"===o.type&&t.preventDefault(),g._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var s=0,r=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;s<r;s++){var a=t[s];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=g._jQueryInterface,e.fn.button.Constructor=g,e.fn.button.noConflict=function(){return e.fn.button=f,g._jQueryInterface};var m="carousel",p=".bs.carousel",_=e.fn[m],v={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},b={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},y={TOUCH:"touch",PEN:"pen"},E=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(c.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(p),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=a(a({},v),t),c.typeCheckConfig(m,t,b),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&y[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&y[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),s=this._items.length-1;if((i&&0===o||n&&o===s)&&!this._config.wrap)return e;var r=(o+("prev"===t?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),s=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(s),s},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,s,r=this,a=this._element.querySelector(".active.carousel-item"),l=this._getItemIndex(a),h=n||a&&this._getItemByDirection(t,a),u=this._getItemIndex(h),d=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",s="left"):(i="carousel-item-right",o="carousel-item-prev",s="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,s).isDefaultPrevented()&&a&&h){this._isSliding=!0,d&&this.pause(),this._setActiveIndicatorElement(h);var f=e.Event("slid.bs.carousel",{relatedTarget:h,direction:s,from:l,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),c.reflow(h),e(a).addClass(i),e(h).addClass(i);var g=parseInt(h.getAttribute("data-interval"),10);g?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=g):this._config.interval=this._config.defaultInterval||this._config.interval;var m=c.getTransitionDurationFromElement(a);e(a).one(c.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(a).removeClass("active "+o+" "+i),r._isSliding=!1,setTimeout((function(){return e(r._element).trigger(f)}),0)})).emulateTransitionEnd(m)}else e(a).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(f);d&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),o=a(a({},v),e(this).data());"object"==typeof n&&(o=a(a({},o),n));var s="string"==typeof n?n:o.slide;if(i||(i=new t(this,o),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof s){if("undefined"==typeof i[s])throw new TypeError('No method named "'+s+'"');i[s]()}else o.interval&&o.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=c.getSelectorFromElement(this);if(i){var o=e(i)[0];if(o&&e(o).hasClass("carousel")){var s=a(a({},e(o).data()),e(this).data()),r=this.getAttribute("data-slide-to");r&&(s.interval=!1),t._jQueryInterface.call(e(o),s),r&&e(o).data("bs.carousel").to(r),n.preventDefault()}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return v}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",E._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);E._jQueryInterface.call(o,o.data())}})),e.fn[m]=E._jQueryInterface,e.fn[m].Constructor=E,e.fn[m].noConflict=function(){return e.fn[m]=_,E._jQueryInterface};var w="collapse",T=e.fn[w],C={toggle:!0,parent:""},S={toggle:"boolean",parent:"(string|element)"},D=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var s=n[i],r=c.getSelectorFromElement(s),a=[].slice.call(document.querySelectorAll(r)).filter((function(e){return e===t}));null!==r&&a.length>0&&(this._selector=r,this._triggerArray.push(s))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var s=e.Event("show.bs.collapse");if(e(this._element).trigger(s),!s.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var r=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[r]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var a="scroll"+(r[0].toUpperCase()+r.slice(1)),l=c.getTransitionDurationFromElement(this._element);e(this._element).one(c.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[r]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(l),this._element.style[r]=this._element[a]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",c.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var s=0;s<o;s++){var r=this._triggerArray[s],a=c.getSelectorFromElement(r);if(null!==a)e([].slice.call(document.querySelectorAll(a))).hasClass("show")||e(r).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var l=c.getTransitionDurationFromElement(this._element);e(this._element).one(c.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(l)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=a(a({},C),t)).toggle=Boolean(t.toggle),c.typeCheckConfig(w,t,S),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;c.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',s=[].slice.call(n.querySelectorAll(o));return e(s).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=c.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.collapse"),s=a(a(a({},C),i.data()),"object"==typeof n&&n?n:{});if(!o&&s.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(s.toggle=!1),o||(o=new t(this,s),i.data("bs.collapse",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return C}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=c.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();D._jQueryInterface.call(t,i)}))})),e.fn[w]=D._jQueryInterface,e.fn[w].Constructor=D,e.fn[w].noConflict=function(){return e.fn[w]=T,D._jQueryInterface};var k="dropdown",N=e.fn[k],A=new RegExp("38|40|27"),I={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},O={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},j=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var i=t.prototype;return i.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},i.show=function(i){if(void 0===i&&(i=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var o={relatedTarget:this._element},s=e.Event("show.bs.dropdown",o),r=t._getParentFromElement(this._element);if(e(r).trigger(s),!s.isDefaultPrevented()){if(!this._inNavbar&&i){if("undefined"==typeof n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var a=this._element;"parent"===this._config.reference?a=r:c.isElement(this._config.reference)&&(a=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(a=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new n(a,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",o))}}},i.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},i.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},i.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},i._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},i._getConfig=function(t){return t=a(a(a({},this.constructor.Default),e(this._element).data()),t),c.typeCheckConfig(k,t,this.constructor.DefaultType),t},i._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},i._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},i._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},i._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=a(a({},e.offsets),t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},i._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),a(a({},t),this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,s=i.length;o<s;o++){var r=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(r).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(r,n.target))){var h=e.Event("hide.bs.dropdown",l);e(r).trigger(h),h.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(r).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=c.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!A.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var s=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==s.length){var r=s.indexOf(n.target);38===n.which&&r>0&&r--,40===n.which&&r<s.length-1&&r++,r<0&&(r=0),s[r].focus()}}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return I}},{key:"DefaultType",get:function(){return O}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',j._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",j._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",j._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),j._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[k]=j._jQueryInterface,e.fn[k].Constructor=j,e.fn[k].noConflict=function(){return e.fn[k]=N,j._jQueryInterface};var P=e.fn.modal,x={backdrop:!0,keyboard:!0,focus:!0,show:!0},L={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},R=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var s=c.getTransitionDurationFromElement(this._element);e(this._element).one(c.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(s)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=a(a({},x),t),c.typeCheckConfig("modal",t,L),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;this._element.classList.add("modal-static");var i=c.getTransitionDurationFromElement(this._element);e(this._element).one(c.TRANSITION_END,(function(){t._element.classList.remove("modal-static")})).emulateTransitionEnd(i),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&c.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var s=e.Event("shown.bs.modal",{relatedTarget:t}),r=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(s)};if(i){var a=c.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(c.TRANSITION_END,r).emulateTransitionEnd(a)}else r()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&c.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=c.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(c.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var s=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var r=c.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(c.TRANSITION_END,s).emulateTransitionEnd(r)}else s()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,s=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(s)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,s=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(s)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,s=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(s)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var o=e(this).data("bs.modal"),s=a(a(a({},x),e(this).data()),"object"==typeof n&&n?n:{});if(o||(o=new t(this,s),e(this).data("bs.modal",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](i)}else s.show&&o.show(i)}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return x}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,o=c.getSelectorFromElement(this);o&&(n=document.querySelector(o));var s=e(n).data("bs.modal")?"toggle":a(a({},e(n).data()),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var r=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||r.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));R._jQueryInterface.call(e(n),s,this)})),e.fn.modal=R._jQueryInterface,e.fn.modal.Constructor=R,e.fn.modal.noConflict=function(){return e.fn.modal=P,R._jQueryInterface};var q=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],F={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Q=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,B=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function H(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),s=[].slice.call(i.body.querySelectorAll("*")),r=function(t,n){var i=s[t],r=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[r]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===q.indexOf(n)||Boolean(t.nodeValue.match(Q)||t.nodeValue.match(B));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,s=i.length;o<s;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=s.length;a<l;a++)r(a);return i.body.innerHTML}var U="tooltip",M=e.fn[U],W=new RegExp("(^|\\s)bs-tooltip\\S+","g"),V=["sanitize","whiteList","sanitizeFn"],z={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},K={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},X={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:F,popperConfig:null},Y={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},$=function(){function t(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var i=t.prototype;return i.enable=function(){this._isEnabled=!0},i.disable=function(){this._isEnabled=!1},i.toggleEnabled=function(){this._isEnabled=!this._isEnabled},i.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},i.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},i.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var i=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(i);var o=c.findShadowRoot(this.element),s=e.contains(null!==o?o:this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),a=c.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&e(r).addClass("fade");var l="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(l);this.addAttachmentClass(h);var u=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(u),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,this._getPopperConfig(h)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var d=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=c.getTransitionDurationFromElement(this.tip);e(this.tip).one(c.TRANSITION_END,d).emulateTransitionEnd(f)}else d()}},i.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),s=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var r=c.getTransitionDurationFromElement(i);e(i).one(c.TRANSITION_END,s).emulateTransitionEnd(r)}else s();this._hoverState=""}},i.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},i.isWithContent=function(){return Boolean(this.getTitle())},i.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},i.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},i.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},i.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=H(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},i.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},i._getPopperConfig=function(t){var e=this;return a(a({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),this.config.popperConfig)},i._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=a(a({},e.offsets),t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},i._getContainer=function(){return!1===this.config.container?document.body:c.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},i._getAttachment=function(t){return K[t.toUpperCase()]},i._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=a(a({},this.config),{},{trigger:"manual",selector:""}):this._fixTitle()},i._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},i._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},i._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},i._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},i._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==V.indexOf(t)&&delete n[t]})),"number"==typeof(t=a(a(a({},this.constructor.Default),n),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),c.typeCheckConfig(U,t,this.constructor.DefaultType),t.sanitize&&(t.template=H(t.template,t.whiteList,t.sanitizeFn)),t},i._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},i._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(W);null!==n&&n.length&&t.removeClass(n.join(""))},i._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},i._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return X}},{key:"NAME",get:function(){return U}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Y}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return z}}]),t}();e.fn[U]=$._jQueryInterface,e.fn[U].Constructor=$,e.fn[U].noConflict=function(){return e.fn[U]=M,$._jQueryInterface};var J="popover",G=e.fn[J],Z=new RegExp("(^|\\s)bs-popover\\S+","g"),tt=a(a({},$.Default),{},{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),et=a(a({},$.DefaultType),{},{content:"(string|element|function)"}),nt={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},it=function(t){var n,i;function s(){return t.apply(this,arguments)||this}i=t,(n=s).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=s.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},r.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},r.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(Z);null!==n&&n.length>0&&t.removeClass(n.join(""))},s._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new s(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},o(s,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return tt}},{key:"NAME",get:function(){return J}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return nt}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return et}}]),s}($);e.fn[J]=it._jQueryInterface,e.fn[J].Constructor=it,e.fn[J].noConflict=function(){return e.fn[J]=G,it._jQueryInterface};var ot="scrollspy",st=e.fn[ot],rt={offset:10,method:"auto",target:""},at={offset:"number",method:"string",target:"(string|element)"},lt=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,s=c.getSelectorFromElement(t);if(s&&(n=document.querySelector(s)),n){var r=n.getBoundingClientRect();if(r.width||r.height)return[e(n)[i]().top+o,s]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=a(a({},rt),"object"==typeof t&&t?t:{})).target&&c.isElement(t.target)){var n=e(t.target).attr("id");n||(n=c.getUID(ot),e(t.target).attr("id",n)),t.target="#"+n}return c.typeCheckConfig(ot,t,at),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"Default",get:function(){return rt}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);lt._jQueryInterface.call(i,i.data())}})),e.fn[ot]=lt._jQueryInterface,e.fn[ot].Constructor=lt,e.fn[ot].noConflict=function(){return e.fn[ot]=st,lt._jQueryInterface};var ct=e.fn.tab,ht=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],s=c.getSelectorFromElement(this._element);if(o){var r="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(r)))[i.length-1]}var a=e.Event("hide.bs.tab",{relatedTarget:this._element}),l=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(a),e(this._element).trigger(l),!l.isDefaultPrevented()&&!a.isDefaultPrevented()){s&&(n=document.querySelector(s)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,s=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],r=i&&s&&e(s).hasClass("fade"),a=function(){return o._transitionComplete(t,s,i)};if(s&&r){var l=c.getTransitionDurationFromElement(s);e(s).removeClass("show").one(c.TRANSITION_END,a).emulateTransitionEnd(l)}else a()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),c.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var s=e(t).closest(".dropdown")[0];if(s){var r=[].slice.call(s.querySelectorAll(".dropdown-toggle"));e(r).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),ht._jQueryInterface.call(e(this),"show")})),e.fn.tab=ht._jQueryInterface,e.fn.tab.Constructor=ht,e.fn.tab.noConflict=function(){return e.fn.tab=ct,ht._jQueryInterface};var ut=e.fn.toast,dt={animation:"boolean",autohide:"boolean",delay:"number"},ft={animation:!0,autohide:!0,delay:500},gt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),c.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=c.getTransitionDurationFromElement(this._element);e(this._element).one(c.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){clearTimeout(this._timeout),this._timeout=null,this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=a(a(a({},ft),e(this._element).data()),"object"==typeof t&&t?t:{}),c.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=c.getTransitionDurationFromElement(this._element);e(this._element).one(c.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.0"}},{key:"DefaultType",get:function(){return dt}},{key:"Default",get:function(){return ft}}]),t}();e.fn.toast=gt._jQueryInterface,e.fn.toast.Constructor=gt,e.fn.toast.noConflict=function(){return e.fn.toast=ut,gt._jQueryInterface},t.Alert=d,t.Button=g,t.Carousel=E,t.Collapse=D,t.Dropdown=j,t.Modal=R,t.Popover=it,t.Scrollspy=lt,t.Tab=ht,t.Toast=gt,t.Tooltip=$,t.Util=c,Object.defineProperty(t,"__esModule",{value:!0})}));
|
7 |
//# sourceMappingURL=bootstrap.min.js.map
|
1 |
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5 |
*/
|
6 |
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}function s(){return(s=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e,n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n;function r(t){var n=this,i=!1;return e(this).one(a.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||a.triggerTransitionEnd(n)}),t),this}var a={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),s=parseFloat(i);return o||s?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],s=e[i],r=s&&a.isElement(s)?"element":null===(l=s)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+r+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};a.jQueryDetection(),e.fn.emulateTransitionEnd=r,e.event.special[a.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var l="alert",c=e.fn[l],h=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=a.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=a.getTransitionDurationFromElement(t);e(t).one(a.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),e.fn[l]=h._jQueryInterface,e.fn[l].Constructor=h,e.fn[l].noConflict=function(){return e.fn[l]=c,h._jQueryInterface};var u=e.fn.button,d=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var s=i.querySelector(".active");s&&e(s).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();("LABEL"!==i.tagName||o&&"checkbox"!==o.type)&&d._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var s=0,r=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;s<r;s++){var a=t[s];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=d._jQueryInterface,e.fn.button.Constructor=d,e.fn.button.noConflict=function(){return e.fn.button=u,d._jQueryInterface};var f="carousel",g=".bs.carousel",m=e.fn[f],p={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},v={TOUCH:"touch",PEN:"pen"},b=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(a.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(g),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=s({},p,t),a.typeCheckConfig(f,t,_),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),s=this._items.length-1;if((i&&0===o||n&&o===s)&&!this._config.wrap)return e;var r=(o+("prev"===t?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),s=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(s),s},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,s,r=this,l=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(l),h=n||l&&this._getItemByDirection(t,l),u=this._getItemIndex(h),d=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",s="left"):(i="carousel-item-right",o="carousel-item-prev",s="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,s).isDefaultPrevented()&&l&&h){this._isSliding=!0,d&&this.pause(),this._setActiveIndicatorElement(h);var f=e.Event("slid.bs.carousel",{relatedTarget:h,direction:s,from:c,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),a.reflow(h),e(l).addClass(i),e(h).addClass(i);var g=parseInt(h.getAttribute("data-interval"),10);g?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=g):this._config.interval=this._config.defaultInterval||this._config.interval;var m=a.getTransitionDurationFromElement(l);e(l).one(a.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(l).removeClass("active "+o+" "+i),r._isSliding=!1,setTimeout((function(){return e(r._element).trigger(f)}),0)})).emulateTransitionEnd(m)}else e(l).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(f);d&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),o=s({},p,e(this).data());"object"==typeof n&&(o=s({},o,n));var r="string"==typeof n?n:o.slide;if(i||(i=new t(this,o),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof r){if("undefined"==typeof i[r])throw new TypeError('No method named "'+r+'"');i[r]()}else o.interval&&o.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=a.getSelectorFromElement(this);if(i){var o=e(i)[0];if(o&&e(o).hasClass("carousel")){var r=s({},e(o).data(),e(this).data()),l=this.getAttribute("data-slide-to");l&&(r.interval=!1),t._jQueryInterface.call(e(o),r),l&&e(o).data("bs.carousel").to(l),n.preventDefault()}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return p}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",b._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);b._jQueryInterface.call(o,o.data())}})),e.fn[f]=b._jQueryInterface,e.fn[f].Constructor=b,e.fn[f].noConflict=function(){return e.fn[f]=m,b._jQueryInterface};var y="collapse",E=e.fn[y],w={toggle:!0,parent:""},T={toggle:"boolean",parent:"(string|element)"},C=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var s=n[i],r=a.getSelectorFromElement(s),l=[].slice.call(document.querySelectorAll(r)).filter((function(e){return e===t}));null!==r&&l.length>0&&(this._selector=r,this._triggerArray.push(s))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var s=e.Event("show.bs.collapse");if(e(this._element).trigger(s),!s.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var r=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[r]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(r[0].toUpperCase()+r.slice(1)),c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[r]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[r]=this._element[l]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",a.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var s=0;s<o;s++){var r=this._triggerArray[s],l=a.getSelectorFromElement(r);if(null!==l)e([].slice.call(document.querySelectorAll(l))).hasClass("show")||e(r).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(c)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=s({},w,t)).toggle=Boolean(t.toggle),a.typeCheckConfig(y,t,T),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;a.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',s=[].slice.call(n.querySelectorAll(o));return e(s).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=a.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.collapse"),r=s({},w,i.data(),"object"==typeof n&&n?n:{});if(!o&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),o||(o=new t(this,r),i.data("bs.collapse",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return w}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=a.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();C._jQueryInterface.call(t,i)}))})),e.fn[y]=C._jQueryInterface,e.fn[y].Constructor=C,e.fn[y].noConflict=function(){return e.fn[y]=E,C._jQueryInterface};var S="dropdown",k=e.fn[S],D=new RegExp("38|40|27"),N={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},A={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},I=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var i=t.prototype;return i.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},i.show=function(i){if(void 0===i&&(i=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var o={relatedTarget:this._element},s=e.Event("show.bs.dropdown",o),r=t._getParentFromElement(this._element);if(e(r).trigger(s),!s.isDefaultPrevented()){if(!this._inNavbar&&i){if("undefined"==typeof n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var l=this._element;"parent"===this._config.reference?l=r:a.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new n(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",o))}}},i.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},i.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},i.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},i._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},i._getConfig=function(t){return t=s({},this.constructor.Default,e(this._element).data(),t),a.typeCheckConfig(S,t,this.constructor.DefaultType),t},i._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},i._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},i._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},i._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},i._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),s({},t,this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,s=i.length;o<s;o++){var r=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(r).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(r,n.target))){var h=e.Event("hide.bs.dropdown",l);e(r).trigger(h),h.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(r).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=a.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!D.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var s=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==s.length){var r=s.indexOf(n.target);38===n.which&&r>0&&r--,40===n.which&&r<s.length-1&&r++,r<0&&(r=0),s[r].focus()}}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return N}},{key:"DefaultType",get:function(){return A}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',I._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",I._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",I._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),I._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[S]=I._jQueryInterface,e.fn[S].Constructor=I,e.fn[S].noConflict=function(){return e.fn[S]=k,I._jQueryInterface};var O=e.fn.modal,j={backdrop:!0,keyboard:!0,focus:!0,show:!0},x={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},P=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var s=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(s)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=s({},j,t),a.typeCheckConfig("modal",t,x),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;var i=this._element.scrollHeight>document.documentElement.clientHeight;i||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=a.getTransitionDurationFromElement(this._dialog);e(this._element).off(a.TRANSITION_END),e(this._element).one(a.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),i||e(t._element).one(a.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&a.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var s=e.Event("shown.bs.modal",{relatedTarget:t}),r=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(s)};if(i){var l=a.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(a.TRANSITION_END,r).emulateTransitionEnd(l)}else r()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&a.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var s=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var r=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,s=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(s)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,s=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(s)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,s=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(s)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var o=e(this).data("bs.modal"),r=s({},j,e(this).data(),"object"==typeof n&&n?n:{});if(o||(o=new t(this,r),e(this).data("bs.modal",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](i)}else r.show&&o.show(i)}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return j}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,o=a.getSelectorFromElement(this);o&&(n=document.querySelector(o));var r=e(n).data("bs.modal")?"toggle":s({},e(n).data(),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var l=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||l.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));P._jQueryInterface.call(e(n),r,this)})),e.fn.modal=P._jQueryInterface,e.fn.modal.Constructor=P,e.fn.modal.noConflict=function(){return e.fn.modal=O,P._jQueryInterface};var R=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],L={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},q=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,F=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Q(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),s=[].slice.call(i.body.querySelectorAll("*")),r=function(t,n){var i=s[t],r=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[r]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===R.indexOf(n)||Boolean(t.nodeValue.match(q)||t.nodeValue.match(F));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,s=i.length;o<s;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=s.length;a<l;a++)r(a);return i.body.innerHTML}var B="tooltip",H=e.fn[B],U=new RegExp("(^|\\s)bs-tooltip\\S+","g"),M=["sanitize","whiteList","sanitizeFn"],W={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},V={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},z={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:L,popperConfig:null},K={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},X=function(){function t(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var i=t.prototype;return i.enable=function(){this._isEnabled=!0},i.disable=function(){this._isEnabled=!1},i.toggleEnabled=function(){this._isEnabled=!this._isEnabled},i.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},i.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},i.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var i=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(i);var o=a.findShadowRoot(this.element),s=e.contains(null!==o?o:this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),l=a.getUID(this.constructor.NAME);r.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&e(r).addClass("fade");var c="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(c);this.addAttachmentClass(h);var u=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(u),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,this._getPopperConfig(h)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var d=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=a.getTransitionDurationFromElement(this.tip);e(this.tip).one(a.TRANSITION_END,d).emulateTransitionEnd(f)}else d()}},i.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),s=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var r=a.getTransitionDurationFromElement(i);e(i).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s();this._hoverState=""}},i.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},i.isWithContent=function(){return Boolean(this.getTitle())},i.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},i.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},i.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},i.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Q(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},i.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},i._getPopperConfig=function(t){var e=this;return s({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},i._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},i._getContainer=function(){return!1===this.config.container?document.body:a.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},i._getAttachment=function(t){return V[t.toUpperCase()]},i._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},i._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},i._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},i._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},i._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},i._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==M.indexOf(t)&&delete n[t]})),"number"==typeof(t=s({},this.constructor.Default,n,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a.typeCheckConfig(B,t,this.constructor.DefaultType),t.sanitize&&(t.template=Q(t.template,t.whiteList,t.sanitizeFn)),t},i._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},i._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(U);null!==n&&n.length&&t.removeClass(n.join(""))},i._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},i._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return z}},{key:"NAME",get:function(){return B}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return K}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return W}}]),t}();e.fn[B]=X._jQueryInterface,e.fn[B].Constructor=X,e.fn[B].noConflict=function(){return e.fn[B]=H,X._jQueryInterface};var Y="popover",$=e.fn[Y],J=new RegExp("(^|\\s)bs-popover\\S+","g"),G=s({},X.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Z=s({},X.DefaultType,{content:"(string|element|function)"}),tt={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},et=function(t){var n,i;function s(){return t.apply(this,arguments)||this}i=t,(n=s).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=s.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},r.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},r.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(J);null!==n&&n.length>0&&t.removeClass(n.join(""))},s._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new s(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},o(s,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return G}},{key:"NAME",get:function(){return Y}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return tt}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Z}}]),s}(X);e.fn[Y]=et._jQueryInterface,e.fn[Y].Constructor=et,e.fn[Y].noConflict=function(){return e.fn[Y]=$,et._jQueryInterface};var nt="scrollspy",it=e.fn[nt],ot={offset:10,method:"auto",target:""},st={offset:"number",method:"string",target:"(string|element)"},rt=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,s=a.getSelectorFromElement(t);if(s&&(n=document.querySelector(s)),n){var r=n.getBoundingClientRect();if(r.width||r.height)return[e(n)[i]().top+o,s]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=s({},ot,"object"==typeof t&&t?t:{})).target&&a.isElement(t.target)){var n=e(t.target).attr("id");n||(n=a.getUID(nt),e(t.target).attr("id",n)),t.target="#"+n}return a.typeCheckConfig(nt,t,st),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return ot}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);rt._jQueryInterface.call(i,i.data())}})),e.fn[nt]=rt._jQueryInterface,e.fn[nt].Constructor=rt,e.fn[nt].noConflict=function(){return e.fn[nt]=it,rt._jQueryInterface};var at=e.fn.tab,lt=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],s=a.getSelectorFromElement(this._element);if(o){var r="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(r)))[i.length-1]}var l=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(l),e(this._element).trigger(c),!c.isDefaultPrevented()&&!l.isDefaultPrevented()){s&&(n=document.querySelector(s)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,s=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],r=i&&s&&e(s).hasClass("fade"),l=function(){return o._transitionComplete(t,s,i)};if(s&&r){var c=a.getTransitionDurationFromElement(s);e(s).removeClass("show").one(a.TRANSITION_END,l).emulateTransitionEnd(c)}else l()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),a.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var s=e(t).closest(".dropdown")[0];if(s){var r=[].slice.call(s.querySelectorAll(".dropdown-toggle"));e(r).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),lt._jQueryInterface.call(e(this),"show")})),e.fn.tab=lt._jQueryInterface,e.fn.tab.Constructor=lt,e.fn.tab.noConflict=function(){return e.fn.tab=at,lt._jQueryInterface};var ct=e.fn.toast,ht={animation:"boolean",autohide:"boolean",delay:"number"},ut={animation:!0,autohide:!0,delay:500},dt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),a.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=s({},ut,e(this._element).data(),"object"==typeof t&&t?t:{}),a.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},n._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"DefaultType",get:function(){return ht}},{key:"Default",get:function(){return ut}}]),t}();e.fn.toast=dt._jQueryInterface,e.fn.toast.Constructor=dt,e.fn.toast.noConflict=function(){return e.fn.toast=ct,dt._jQueryInterface},t.Alert=h,t.Button=d,t.Carousel=b,t.Collapse=C,t.Dropdown=I,t.Modal=P,t.Popover=et,t.Scrollspy=rt,t.Tab=lt,t.Toast=dt,t.Tooltip=X,t.Util=a,Object.defineProperty(t,"__esModule",{value:!0})}));
|
7 |
//# sourceMappingURL=bootstrap.min.js.map
|
resources/js/global-plugin.js
CHANGED
@@ -38,21 +38,41 @@ var iCWP_WPSF_SecurityAdmin = new function () {
|
|
38 |
};
|
39 |
}();
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
var iCWP_WPSF_StandardAjax = new function () {
|
42 |
this.send_ajax_req = function ( reqData ) {
|
43 |
iCWP_WPSF_BodyOverlay.show();
|
44 |
|
45 |
-
jQuery.
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
if ( typeof iCWP_WPSF_Toaster !== 'undefined' ) {
|
49 |
-
iCWP_WPSF_Toaster.showMessage(
|
50 |
}
|
51 |
else {
|
52 |
-
iCWP_WPSF_Growl.showMessage(
|
53 |
}
|
54 |
|
55 |
-
if (
|
56 |
setTimeout( function () {
|
57 |
location.reload();
|
58 |
}, 2000 );
|
@@ -61,9 +81,7 @@ var iCWP_WPSF_StandardAjax = new function () {
|
|
61 |
iCWP_WPSF_BodyOverlay.hide();
|
62 |
}
|
63 |
}
|
64 |
-
|
65 |
-
}
|
66 |
-
);
|
67 |
};
|
68 |
}();
|
69 |
|
@@ -305,8 +323,6 @@ var iCWP_WPSF_Growl = new function () {
|
|
305 |
}, 4000 );
|
306 |
};
|
307 |
|
308 |
-
/**
|
309 |
-
*/
|
310 |
var createDynDiv = function ( sClass ) {
|
311 |
var $oDiv = jQuery( '<div />' ).appendTo( 'body' );
|
312 |
$oDiv.attr( 'id', 'icwp-growl-notice' + Math.floor( (Math.random() * 100) + 1 ) );
|
38 |
};
|
39 |
}();
|
40 |
|
41 |
+
var iCWP_WPSF_ParseAjaxResponse = new function () {
|
42 |
+
this.parseIt = function ( raw ) {
|
43 |
+
let parsed = {};
|
44 |
+
try {
|
45 |
+
parsed = JSON.parse( raw );
|
46 |
+
}
|
47 |
+
catch ( e ) {
|
48 |
+
parsed = JSON.parse(
|
49 |
+
raw.substring( raw.indexOf( '{' ), raw.lastIndexOf( '}' ) + 1 )
|
50 |
+
);
|
51 |
+
}
|
52 |
+
return parsed;
|
53 |
+
};
|
54 |
+
}();
|
55 |
+
|
56 |
var iCWP_WPSF_StandardAjax = new function () {
|
57 |
this.send_ajax_req = function ( reqData ) {
|
58 |
iCWP_WPSF_BodyOverlay.show();
|
59 |
|
60 |
+
jQuery.ajax( {
|
61 |
+
type: "POST",
|
62 |
+
url: ajaxurl,
|
63 |
+
data: reqData,
|
64 |
+
dataType: "text",
|
65 |
+
success: function ( raw ) {
|
66 |
+
let resp = iCWP_WPSF_ParseAjaxResponse.parseIt( raw );
|
67 |
|
68 |
if ( typeof iCWP_WPSF_Toaster !== 'undefined' ) {
|
69 |
+
iCWP_WPSF_Toaster.showMessage( resp.data.message, resp.success );
|
70 |
}
|
71 |
else {
|
72 |
+
iCWP_WPSF_Growl.showMessage( resp.data.message, resp.success );
|
73 |
}
|
74 |
|
75 |
+
if ( resp.data.page_reload ) {
|
76 |
setTimeout( function () {
|
77 |
location.reload();
|
78 |
}, 2000 );
|
81 |
iCWP_WPSF_BodyOverlay.hide();
|
82 |
}
|
83 |
}
|
84 |
+
} )
|
|
|
|
|
85 |
};
|
86 |
}();
|
87 |
|
323 |
}, 4000 );
|
324 |
};
|
325 |
|
|
|
|
|
326 |
var createDynDiv = function ( sClass ) {
|
327 |
var $oDiv = jQuery( '<div />' ).appendTo( 'body' );
|
328 |
$oDiv.attr( 'id', 'icwp-growl-notice' + Math.floor( (Math.random() * 100) + 1 ) );
|
resources/js/plugin.js
CHANGED
@@ -47,17 +47,23 @@ var iCWP_WPSF_OptionsPages = new function () {
|
|
47 |
}();
|
48 |
|
49 |
let iCWP_WPSF_OptsPageRender = new function () {
|
50 |
-
this.renderForm = function (
|
51 |
iCWP_WPSF_BodyOverlay.show();
|
52 |
-
jQuery.
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
-
).
|
58 |
function () {
|
59 |
-
}
|
60 |
-
).always( function () {
|
61 |
iCWP_WPSF_BodyOverlay.hide();
|
62 |
}
|
63 |
);
|
@@ -120,8 +126,6 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
|
|
120 |
aAjaxReqParams = aParams;
|
121 |
};
|
122 |
|
123 |
-
/**
|
124 |
-
*/
|
125 |
var submitOptionsForm = function ( event ) {
|
126 |
iCWP_WPSF_BodyOverlay.show();
|
127 |
|
@@ -229,8 +233,6 @@ if ( typeof icwp_wpsf_vars_secadmin !== 'undefined' && icwp_wpsf_vars_secadmin.t
|
|
229 |
var bWarningShown = false;
|
230 |
var nIntervalTimeout = 500 * icwp_wpsf_vars_secadmin.timeleft;
|
231 |
|
232 |
-
/**
|
233 |
-
*/
|
234 |
var checkSecAdmin = function () {
|
235 |
|
236 |
bCheckInPlace = false;
|
47 |
}();
|
48 |
|
49 |
let iCWP_WPSF_OptsPageRender = new function () {
|
50 |
+
this.renderForm = function ( reqData ) {
|
51 |
iCWP_WPSF_BodyOverlay.show();
|
52 |
+
jQuery.ajax(
|
53 |
+
{
|
54 |
+
type: "POST",
|
55 |
+
url: ajaxurl,
|
56 |
+
data: reqData,
|
57 |
+
dataType: "text",
|
58 |
+
success: function ( rawResponse ) {
|
59 |
+
let response = iCWP_WPSF_ParseAjaxResponse.parseIt( rawResponse );
|
60 |
+
jQuery( '#ColumnOptions .content-options' )
|
61 |
+
.html( response.data.html )
|
62 |
+
.trigger( 'odp-optsrender' );
|
63 |
+
}
|
64 |
}
|
65 |
+
).always(
|
66 |
function () {
|
|
|
|
|
67 |
iCWP_WPSF_BodyOverlay.hide();
|
68 |
}
|
69 |
);
|
126 |
aAjaxReqParams = aParams;
|
127 |
};
|
128 |
|
|
|
|
|
129 |
var submitOptionsForm = function ( event ) {
|
130 |
iCWP_WPSF_BodyOverlay.show();
|
131 |
|
233 |
var bWarningShown = false;
|
234 |
var nIntervalTimeout = 500 * icwp_wpsf_vars_secadmin.timeleft;
|
235 |
|
|
|
|
|
236 |
var checkSecAdmin = function () {
|
237 |
|
238 |
bCheckInPlace = false;
|
src/config/feature-autoupdates.php
CHANGED
@@ -150,9 +150,9 @@
|
|
150 |
],
|
151 |
"link_info": "https://shsec.io/3x",
|
152 |
"link_blog": "",
|
153 |
-
"name": "
|
154 |
-
"summary": "
|
155 |
-
"description": "
|
156 |
},
|
157 |
{
|
158 |
"key": "enable_upgrade_notification_email",
|
150 |
],
|
151 |
"link_info": "https://shsec.io/3x",
|
152 |
"link_blog": "",
|
153 |
+
"name": "Auto Update Plugin",
|
154 |
+
"summary": "Always Automatically Update This Plugin",
|
155 |
+
"description": "Regardless of any other settings, automatically update the Shield plugin."
|
156 |
},
|
157 |
{
|
158 |
"key": "enable_upgrade_notification_email",
|
src/config/feature-comments_filter.php
CHANGED
@@ -8,7 +8,6 @@
|
|
8 |
"show_module_options": true,
|
9 |
"storage_key": "commentsfilter",
|
10 |
"tagline": "Block comment SPAM and retain your privacy",
|
11 |
-
"use_sessions": true,
|
12 |
"show_central": true,
|
13 |
"access_restricted": true,
|
14 |
"premium": false,
|
8 |
"show_module_options": true,
|
9 |
"storage_key": "commentsfilter",
|
10 |
"tagline": "Block comment SPAM and retain your privacy",
|
|
|
11 |
"show_central": true,
|
12 |
"access_restricted": true,
|
13 |
"premium": false,
|
src/config/feature-hack_protect.php
CHANGED
@@ -195,6 +195,10 @@
|
|
195 |
{
|
196 |
"value_key": "root_index",
|
197 |
"text": "Root index.php"
|
|
|
|
|
|
|
|
|
198 |
}
|
199 |
],
|
200 |
"link_info": "https://shsec.io/h7",
|
195 |
{
|
196 |
"value_key": "root_index",
|
197 |
"text": "Root index.php"
|
198 |
+
},
|
199 |
+
{
|
200 |
+
"value_key": "root_webconfig",
|
201 |
+
"text": "Root Web.Config"
|
202 |
}
|
203 |
],
|
204 |
"link_info": "https://shsec.io/h7",
|
src/config/feature-ips.php
CHANGED
@@ -21,7 +21,7 @@
|
|
21 |
"id": "visitor-whitelisted",
|
22 |
"schedule": "conditions",
|
23 |
"plugin_page_only": true,
|
24 |
-
"per_user":
|
25 |
"type": "info"
|
26 |
}
|
27 |
},
|
@@ -167,16 +167,16 @@
|
|
167 |
"key": "user_auto_recover",
|
168 |
"section": "section_auto_black_list",
|
169 |
"premium": true,
|
170 |
-
"default":
|
171 |
-
"type": "
|
172 |
"value_options": [
|
173 |
-
{
|
174 |
-
"value_key": "disabled",
|
175 |
-
"text": "Disabled"
|
176 |
-
},
|
177 |
{
|
178 |
"value_key": "gasp",
|
179 |
"text": "With Shield Bot Protection"
|
|
|
|
|
|
|
|
|
180 |
}
|
181 |
],
|
182 |
"link_info": "https://shsec.io/f8",
|
@@ -186,16 +186,16 @@
|
|
186 |
"description": "Allow visitors blocked by the plugin to automatically unblock themselves."
|
187 |
},
|
188 |
{
|
189 |
-
"key":
|
190 |
-
"section":
|
191 |
-
"premium":
|
192 |
-
"default":
|
193 |
-
"type":
|
194 |
-
"link_info":
|
195 |
-
"link_blog":
|
196 |
-
"name":
|
197 |
-
"summary":
|
198 |
-
"description":
|
199 |
},
|
200 |
{
|
201 |
"key": "text_loginfailed",
|
@@ -317,7 +317,6 @@
|
|
317 |
"section": "section_logins",
|
318 |
"default": "transgression-single",
|
319 |
"type": "select",
|
320 |
-
"default": "log",
|
321 |
"value_options": [
|
322 |
{
|
323 |
"value_key": "disabled",
|
@@ -467,26 +466,30 @@
|
|
467 |
"transferable": false,
|
468 |
"type": "array",
|
469 |
"default": []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
}
|
471 |
],
|
472 |
"definitions": {
|
473 |
-
"db_classes":
|
474 |
"ips": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
475 |
},
|
476 |
"ip_lists_table_name": "ip_lists",
|
477 |
-
"ip_list_table_columns":
|
478 |
-
"
|
479 |
-
"
|
480 |
-
"
|
481 |
-
"
|
482 |
-
"
|
483 |
-
"
|
484 |
-
"
|
485 |
-
"
|
486 |
-
|
487 |
-
"created_at",
|
488 |
-
"deleted_at"
|
489 |
-
],
|
490 |
"events": {
|
491 |
"custom_offense": {
|
492 |
"cat": 3,
|
21 |
"id": "visitor-whitelisted",
|
22 |
"schedule": "conditions",
|
23 |
"plugin_page_only": true,
|
24 |
+
"per_user": true,
|
25 |
"type": "info"
|
26 |
}
|
27 |
},
|
167 |
"key": "user_auto_recover",
|
168 |
"section": "section_auto_black_list",
|
169 |
"premium": true,
|
170 |
+
"default": [],
|
171 |
+
"type": "multiple_select",
|
172 |
"value_options": [
|
|
|
|
|
|
|
|
|
173 |
{
|
174 |
"value_key": "gasp",
|
175 |
"text": "With Shield Bot Protection"
|
176 |
+
},
|
177 |
+
{
|
178 |
+
"value_key": "email",
|
179 |
+
"text": "Magic Email Links To Unblock Logged-In Users"
|
180 |
}
|
181 |
],
|
182 |
"link_info": "https://shsec.io/f8",
|
186 |
"description": "Allow visitors blocked by the plugin to automatically unblock themselves."
|
187 |
},
|
188 |
{
|
189 |
+
"key": "request_whitelist",
|
190 |
+
"section": "section_auto_black_list",
|
191 |
+
"premium": true,
|
192 |
+
"default": [],
|
193 |
+
"type": "array",
|
194 |
+
"link_info": "https://shsec.io/gd",
|
195 |
+
"link_blog": "",
|
196 |
+
"name": "Request Path Whitelist",
|
197 |
+
"summary": "Request Path Whitelist",
|
198 |
+
"description": "Request Path Whitelist."
|
199 |
},
|
200 |
{
|
201 |
"key": "text_loginfailed",
|
317 |
"section": "section_logins",
|
318 |
"default": "transgression-single",
|
319 |
"type": "select",
|
|
|
320 |
"value_options": [
|
321 |
{
|
322 |
"value_key": "disabled",
|
466 |
"transferable": false,
|
467 |
"type": "array",
|
468 |
"default": []
|
469 |
+
},
|
470 |
+
{
|
471 |
+
"key": "autounblock_emailids",
|
472 |
+
"section": "section_non_ui",
|
473 |
+
"transferable": false,
|
474 |
+
"type": "array",
|
475 |
+
"default": []
|
476 |
}
|
477 |
],
|
478 |
"definitions": {
|
479 |
+
"db_classes": {
|
480 |
"ips": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
481 |
},
|
482 |
"ip_lists_table_name": "ip_lists",
|
483 |
+
"ip_list_table_columns": {
|
484 |
+
"ip": "varchar(60) NOT NULL DEFAULT '' COMMENT 'Human readable IP address or range'",
|
485 |
+
"label": "varchar(255) NOT NULL DEFAULT ''",
|
486 |
+
"list": "varchar(4) NOT NULL DEFAULT ''",
|
487 |
+
"ip6": "tinyint(1) UNSIGNED NOT NULL DEFAULT 0",
|
488 |
+
"is_range": "tinyint(1) UNSIGNED NOT NULL DEFAULT 0",
|
489 |
+
"transgressions": "int(10) UNSIGNED NOT NULL DEFAULT 0",
|
490 |
+
"last_access_at": "int(15) UNSIGNED NOT NULL DEFAULT 0",
|
491 |
+
"blocked_at": "int(15) UNSIGNED NOT NULL DEFAULT 0"
|
492 |
+
},
|
|
|
|
|
|
|
493 |
"events": {
|
494 |
"custom_offense": {
|
495 |
"cat": 3,
|
src/config/feature-lockdown.php
CHANGED
@@ -131,26 +131,37 @@
|
|
131 |
"description": "Please only enable this option if you have a valid SSL certificate installed. Equivalent to setting 'FORCE_SSL_ADMIN' to TRUE."
|
132 |
},
|
133 |
{
|
134 |
-
"key": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
"section": "section_wordpress_obscurity_options",
|
136 |
"default": "N",
|
137 |
"type": "checkbox",
|
138 |
"link_info": "",
|
139 |
"link_blog": "",
|
140 |
-
"name": "WP
|
141 |
-
"summary": "
|
142 |
-
"description": "
|
143 |
},
|
144 |
{
|
145 |
-
"key": "
|
146 |
"section": "section_wordpress_obscurity_options",
|
147 |
-
"default": "
|
148 |
"type": "checkbox",
|
149 |
-
"link_info": "
|
150 |
"link_blog": "",
|
151 |
-
"name": "
|
152 |
-
"summary": "
|
153 |
-
"description": "
|
154 |
}
|
155 |
],
|
156 |
"definitions": {
|
131 |
"description": "Please only enable this option if you have a valid SSL certificate installed. Equivalent to setting 'FORCE_SSL_ADMIN' to TRUE."
|
132 |
},
|
133 |
{
|
134 |
+
"key": "block_author_discovery",
|
135 |
+
"section": "section_wordpress_obscurity_options",
|
136 |
+
"default": "Y",
|
137 |
+
"type": "checkbox",
|
138 |
+
"link_info": "https://shsec.io/wpsf23",
|
139 |
+
"link_blog": "",
|
140 |
+
"name": "Block Username Fishing",
|
141 |
+
"summary": "Block the ability to discover WordPress usernames based on author IDs",
|
142 |
+
"description": "When enabled, any URL requests containing 'author=' will be killed. Warning: Enabling this option may interfere with expected operations of your site."
|
143 |
+
},
|
144 |
+
{
|
145 |
+
"key": "clean_wp_rubbish",
|
146 |
"section": "section_wordpress_obscurity_options",
|
147 |
"default": "N",
|
148 |
"type": "checkbox",
|
149 |
"link_info": "",
|
150 |
"link_blog": "",
|
151 |
+
"name": "Clean WP Files",
|
152 |
+
"summary": "Automatically Delete Unnecessary WP Files",
|
153 |
+
"description": "Automatically delete WordPress files like wp-config-sample.php."
|
154 |
},
|
155 |
{
|
156 |
+
"key": "hide_wordpress_generator_tag",
|
157 |
"section": "section_wordpress_obscurity_options",
|
158 |
+
"default": "N",
|
159 |
"type": "checkbox",
|
160 |
+
"link_info": "",
|
161 |
"link_blog": "",
|
162 |
+
"name": "WP Generator Tag",
|
163 |
+
"summary": "Remove WP Generator Meta Tag",
|
164 |
+
"description": "Remove a meta tag from your WordPress pages that publicly displays that your site is WordPress and its current version."
|
165 |
}
|
166 |
],
|
167 |
"definitions": {
|
src/config/feature-login_protect.php
CHANGED
@@ -370,8 +370,8 @@
|
|
370 |
"premium": true,
|
371 |
"default": "N",
|
372 |
"type": "checkbox",
|
373 |
-
"link_info": "https://shsec.io/
|
374 |
-
"link_blog": "
|
375 |
"name": "Allow U2F",
|
376 |
"summary": "Allow Registration Of U2F Devices",
|
377 |
"description": "Allow Registration Of U2F Devices."
|
370 |
"premium": true,
|
371 |
"default": "N",
|
372 |
"type": "checkbox",
|
373 |
+
"link_info": "https://shsec.io/i9",
|
374 |
+
"link_blog": "",
|
375 |
"name": "Allow U2F",
|
376 |
"summary": "Allow Registration Of U2F Devices",
|
377 |
"description": "Allow Registration Of U2F Devices."
|
src/config/feature-plugin.php
CHANGED
@@ -34,6 +34,14 @@
|
|
34 |
"can_dismiss": false,
|
35 |
"type": "error"
|
36 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
"php7": {
|
38 |
"id": "php7",
|
39 |
"schedule": "conditions",
|
@@ -62,10 +70,6 @@
|
|
62 |
"type": "promo",
|
63 |
"drip_form_id": "250437573"
|
64 |
},
|
65 |
-
"plugin-update-available": {
|
66 |
-
"id": "plugin-update-available",
|
67 |
-
"type": "warning"
|
68 |
-
},
|
69 |
"allow-tracking": {
|
70 |
"id": "allow-tracking",
|
71 |
"plugin_admin": true,
|
34 |
"can_dismiss": false,
|
35 |
"type": "error"
|
36 |
},
|
37 |
+
"update-available": {
|
38 |
+
"id": "update-available",
|
39 |
+
"schedule": "conditions",
|
40 |
+
"valid_admin": true,
|
41 |
+
"plugin_page_only": true,
|
42 |
+
"can_dismiss": false,
|
43 |
+
"type": "error"
|
44 |
+
},
|
45 |
"php7": {
|
46 |
"id": "php7",
|
47 |
"schedule": "conditions",
|
70 |
"type": "promo",
|
71 |
"drip_form_id": "250437573"
|
72 |
},
|
|
|
|
|
|
|
|
|
73 |
"allow-tracking": {
|
74 |
"id": "allow-tracking",
|
75 |
"plugin_admin": true,
|
src/features/admin_access_restriction.php
CHANGED
@@ -13,8 +13,6 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
13 |
*/
|
14 |
private $bValidSecAdminRequest;
|
15 |
|
16 |
-
/**
|
17 |
-
*/
|
18 |
protected function setupCustomHooks() {
|
19 |
parent::setupCustomHooks();
|
20 |
add_action( $this->prefix( 'pre_deactivate_plugin' ), [ $this, 'preDeactivatePlugin' ] );
|
@@ -30,32 +28,29 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
30 |
|
31 |
/**
|
32 |
* @return array
|
33 |
-
* @deprecated 9.
|
34 |
*/
|
35 |
public function getSecurityAdminUsers() {
|
36 |
$aU = $this->getOpt( 'sec_admin_users', [] );
|
37 |
return ( is_array( $aU ) && $this->isPremium() ) ? $aU : [];
|
38 |
}
|
39 |
|
40 |
-
/**
|
41 |
-
* @return bool
|
42 |
-
* @deprecated 9.1.0
|
43 |
-
*/
|
44 |
-
public function hasSecAdminUsers() {
|
45 |
-
return count( $this->getSecurityAdminUsers() ) > 0;
|
46 |
-
}
|
47 |
-
|
48 |
/**
|
49 |
* No checking of admin capabilities in-case of infinite loop with
|
50 |
* admin access caps check
|
51 |
* @return bool
|
52 |
*/
|
53 |
public function isRegisteredSecAdminUser() {
|
|
|
|
|
54 |
$sUser = Services::WpUsers()->getCurrentWpUsername();
|
55 |
-
return !empty( $sUser ) && in_array( $sUser, $
|
56 |
}
|
57 |
|
58 |
protected function preProcessOptions() {
|
|
|
|
|
|
|
59 |
if ( $this->isValidSecAdminRequest() ) {
|
60 |
$this->setSecurityAdminStatusOnOff( true );
|
61 |
}
|
@@ -75,7 +70,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
75 |
}
|
76 |
}
|
77 |
|
78 |
-
$this->setOpt( 'sec_admin_users', $this->verifySecAdminUsers( $
|
79 |
}
|
80 |
|
81 |
/**
|
@@ -86,8 +81,8 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
86 |
private function verifySecAdminUsers( $aSecUsers ) {
|
87 |
$oDP = Services::Data();
|
88 |
$oWpUsers = Services::WpUsers();
|
89 |
-
/** @var SecurityAdmin\Options $
|
90 |
-
$
|
91 |
|
92 |
$aFiltered = [];
|
93 |
foreach ( $aSecUsers as $nCurrentKey => $sUsernameOrEmail ) {
|
@@ -109,7 +104,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
109 |
// We now run a bit of a sanity check to ensure that the current user is
|
110 |
// not adding users here that aren't themselves without a key to still gain access
|
111 |
$oCurrent = $oWpUsers->getCurrentWpUser();
|
112 |
-
if ( !empty( $aFiltered ) && !$
|
113 |
$aFiltered[] = $oCurrent->user_login;
|
114 |
}
|
115 |
|
@@ -169,11 +164,11 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
169 |
* @return bool
|
170 |
*/
|
171 |
public function isEnabledSecurityAdmin() {
|
172 |
-
/** @var SecurityAdmin\Options $
|
173 |
-
$
|
174 |
return $this->isModOptEnabled() &&
|
175 |
-
( count( $
|
176 |
-
( $
|
177 |
);
|
178 |
}
|
179 |
|
@@ -204,14 +199,14 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
204 |
$bValid = false;
|
205 |
$sReqKey = Services::Request()->post( 'sec_admin_key' );
|
206 |
if ( !empty( $sReqKey ) ) {
|
207 |
-
/** @var SecurityAdmin\Options $
|
208 |
-
$
|
209 |
-
$bValid = hash_equals( $
|
210 |
if ( !$bValid ) {
|
211 |
$sEscaped = isset( $_POST[ 'sec_admin_key' ] ) ? $_POST[ 'sec_admin_key' ] : '';
|
212 |
if ( !empty( $sEscaped ) ) {
|
213 |
// Workaround for escaping of passwords
|
214 |
-
$bValid = hash_equals( $
|
215 |
if ( $bValid ) {
|
216 |
$this->setOpt( 'admin_access_key', md5( $sReqKey ) );
|
217 |
}
|
@@ -234,13 +229,13 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
234 |
}
|
235 |
|
236 |
/**
|
237 |
-
* @param string $
|
238 |
* @return bool
|
239 |
*/
|
240 |
-
public function verifyAccessKey( $
|
241 |
-
/** @var SecurityAdmin\Options $
|
242 |
-
$
|
243 |
-
return !empty( $
|
244 |
}
|
245 |
|
246 |
/**
|
@@ -292,31 +287,13 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
292 |
return $sLogoUrl;
|
293 |
}
|
294 |
|
295 |
-
/**
|
296 |
-
* @param string $sSection
|
297 |
-
* @return array
|
298 |
-
*/
|
299 |
-
protected function getSectionWarnings( $sSection ) {
|
300 |
-
$aWarnings = [];
|
301 |
-
|
302 |
-
switch ( $sSection ) {
|
303 |
-
case 'section_whitelabel':
|
304 |
-
if ( !$this->isEnabledSecurityAdmin() ) {
|
305 |
-
$aWarnings[] = __( 'Please also supply a Security Admin PIN, as whitelabel settings are only applied when the Security Admin feature is active.', 'wp-simple-firewall' );
|
306 |
-
}
|
307 |
-
break;
|
308 |
-
}
|
309 |
-
|
310 |
-
return $aWarnings;
|
311 |
-
}
|
312 |
-
|
313 |
/**
|
314 |
* @return bool
|
315 |
*/
|
316 |
public function isWlEnabled() {
|
317 |
-
/** @var SecurityAdmin\Options $
|
318 |
-
$
|
319 |
-
return $
|
320 |
}
|
321 |
|
322 |
/**
|
@@ -381,120 +358,22 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
381 |
}
|
382 |
}
|
383 |
|
384 |
-
/**
|
385 |
-
* @param array $aAllData
|
386 |
-
* @return array
|
387 |
-
*/
|
388 |
-
public function addInsightsConfigData( $aAllData ) {
|
389 |
-
/** @var SecurityAdmin\Options $oOpts */
|
390 |
-
$oOpts = $this->getOptions();
|
391 |
-
|
392 |
-
$aThis = [
|
393 |
-
'strings' => [
|
394 |
-
'title' => __( 'Security Admin', 'wp-simple-firewall' ),
|
395 |
-
'sub' => sprintf( __( 'Prevent Tampering With %s Settings', 'wp-simple-firewall' ), $this->getCon()
|
396 |
-
->getHumanName() ),
|
397 |
-
],
|
398 |
-
'key_opts' => [],
|
399 |
-
'href_options' => $this->getUrl_AdminPage()
|
400 |
-
];
|
401 |
-
|
402 |
-
if ( !$this->isEnabledForUiSummary() ) {
|
403 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
404 |
-
}
|
405 |
-
else {
|
406 |
-
$aThis[ 'key_opts' ][ 'mod' ] = [
|
407 |
-
'name' => __( 'Security Admin', 'wp-simple-firewall' ),
|
408 |
-
'enabled' => $this->isEnabledForUiSummary(),
|
409 |
-
'summary' => $this->isEnabledForUiSummary() ?
|
410 |
-
__( 'Security plugin is protected against tampering', 'wp-simple-firewall' )
|
411 |
-
: __( 'Security plugin is vulnerable to tampering', 'wp-simple-firewall' ),
|
412 |
-
'weight' => 2,
|
413 |
-
'href' => $this->getUrl_DirectLinkToOption( 'admin_access_key' ),
|
414 |
-
];
|
415 |
-
|
416 |
-
$bWpOpts = $oOpts->getAdminAccessArea_Options();
|
417 |
-
$aThis[ 'key_opts' ][ 'wpopts' ] = [
|
418 |
-
'name' => __( 'Important Options', 'wp-simple-firewall' ),
|
419 |
-
'enabled' => $bWpOpts,
|
420 |
-
'summary' => $bWpOpts ?
|
421 |
-
__( 'Important WP options are protected against tampering', 'wp-simple-firewall' )
|
422 |
-
: __( "Important WP options aren't protected against tampering", 'wp-simple-firewall' ),
|
423 |
-
'weight' => 2,
|
424 |
-
'href' => $this->getUrl_DirectLinkToOption( 'admin_access_restrict_options' ),
|
425 |
-
];
|
426 |
-
|
427 |
-
$bUsers = $oOpts->isSecAdminRestrictUsersEnabled();
|
428 |
-
$aThis[ 'key_opts' ][ 'adminusers' ] = [
|
429 |
-
'name' => __( 'WP Admins', 'wp-simple-firewall' ),
|
430 |
-
'enabled' => $bUsers,
|
431 |
-
'summary' => $bUsers ?
|
432 |
-
__( 'Admin users are protected against tampering', 'wp-simple-firewall' )
|
433 |
-
: __( "Admin users aren't protected against tampering", 'wp-simple-firewall' ),
|
434 |
-
'weight' => 1,
|
435 |
-
'href' => $this->getUrl_DirectLinkToOption( 'admin_access_restrict_admin_users' ),
|
436 |
-
];
|
437 |
-
}
|
438 |
-
|
439 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
440 |
-
return $aAllData;
|
441 |
-
}
|
442 |
-
|
443 |
-
/**
|
444 |
-
* @param array $aAllNotices
|
445 |
-
* @return array
|
446 |
-
*/
|
447 |
-
public function addInsightsNoticeData( $aAllNotices ) {
|
448 |
-
|
449 |
-
$aNotices = [
|
450 |
-
'title' => __( 'Security Admin Protection', 'wp-simple-firewall' ),
|
451 |
-
'messages' => []
|
452 |
-
];
|
453 |
-
|
454 |
-
{//sec admin
|
455 |
-
if ( !$this->isEnabledSecurityAdmin() ) {
|
456 |
-
$aNotices[ 'messages' ][ 'sec_admin' ] = [
|
457 |
-
'title' => __( 'Security Plugin Unprotected', 'wp-simple-firewall' ),
|
458 |
-
'message' => sprintf(
|
459 |
-
__( "The Security Admin protection is not active.", 'wp-simple-firewall' ),
|
460 |
-
$this->getCon()->getHumanName()
|
461 |
-
),
|
462 |
-
'href' => $this->getUrl_AdminPage(),
|
463 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options' ) ),
|
464 |
-
'rec' => __( 'Security Admin should be turned-on to protect your security settings.', 'wp-simple-firewall' )
|
465 |
-
];
|
466 |
-
}
|
467 |
-
}
|
468 |
-
|
469 |
-
$aNotices[ 'count' ] = count( $aNotices[ 'messages' ] );
|
470 |
-
$aAllNotices[ 'sec_admin' ] = $aNotices;
|
471 |
-
|
472 |
-
return $aAllNotices;
|
473 |
-
}
|
474 |
-
|
475 |
-
/**
|
476 |
-
* @return bool
|
477 |
-
*/
|
478 |
-
protected function isEnabledForUiSummary() {
|
479 |
-
return parent::isEnabledForUiSummary() && $this->isEnabledSecurityAdmin();
|
480 |
-
}
|
481 |
-
|
482 |
/**
|
483 |
* This is the point where you would want to do any options verification
|
484 |
*/
|
485 |
protected function doPrePluginOptionsSave() {
|
486 |
-
/** @var SecurityAdmin\Options $
|
487 |
-
$
|
488 |
|
489 |
-
if ( hash_equals( $
|
490 |
-
$
|
491 |
$this->setSecurityAdminStatusOnOff( false );
|
492 |
}
|
493 |
|
494 |
// Restricting Activate Plugins also means restricting the rest.
|
495 |
-
$aPluginsRestrictions = $
|
496 |
if ( in_array( 'activate_plugins', $aPluginsRestrictions ) ) {
|
497 |
-
$
|
498 |
'admin_access_restrict_plugins',
|
499 |
array_unique( array_merge( $aPluginsRestrictions, [
|
500 |
'install_plugins',
|
@@ -505,9 +384,9 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
505 |
}
|
506 |
|
507 |
// Restricting Switch (Activate) Themes also means restricting the rest.
|
508 |
-
$aThemesRestrictions = $
|
509 |
if ( in_array( 'switch_themes', $aThemesRestrictions ) && in_array( 'edit_theme_options', $aThemesRestrictions ) ) {
|
510 |
-
$
|
511 |
'admin_access_restrict_themes',
|
512 |
array_unique( array_merge( $aThemesRestrictions, [
|
513 |
'install_themes',
|
@@ -517,17 +396,15 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
517 |
);
|
518 |
}
|
519 |
|
520 |
-
$aPostRestrictions = $
|
521 |
if ( in_array( 'edit', $aPostRestrictions ) ) {
|
522 |
-
$
|
523 |
'admin_access_restrict_posts',
|
524 |
array_unique( array_merge( $aPostRestrictions, [ 'create', 'publish', 'delete' ] ) )
|
525 |
);
|
526 |
}
|
527 |
}
|
528 |
|
529 |
-
/**
|
530 |
-
*/
|
531 |
public function preDeactivatePlugin() {
|
532 |
if ( !$this->getCon()->isPluginAdmin() ) {
|
533 |
Services::WpGeneral()->wpDie(
|
13 |
*/
|
14 |
private $bValidSecAdminRequest;
|
15 |
|
|
|
|
|
16 |
protected function setupCustomHooks() {
|
17 |
parent::setupCustomHooks();
|
18 |
add_action( $this->prefix( 'pre_deactivate_plugin' ), [ $this, 'preDeactivatePlugin' ] );
|
28 |
|
29 |
/**
|
30 |
* @return array
|
31 |
+
* @deprecated 9.2.0
|
32 |
*/
|
33 |
public function getSecurityAdminUsers() {
|
34 |
$aU = $this->getOpt( 'sec_admin_users', [] );
|
35 |
return ( is_array( $aU ) && $this->isPremium() ) ? $aU : [];
|
36 |
}
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
/**
|
39 |
* No checking of admin capabilities in-case of infinite loop with
|
40 |
* admin access caps check
|
41 |
* @return bool
|
42 |
*/
|
43 |
public function isRegisteredSecAdminUser() {
|
44 |
+
/** @var SecurityAdmin\Options $opts */
|
45 |
+
$opts = $this->getOptions();
|
46 |
$sUser = Services::WpUsers()->getCurrentWpUsername();
|
47 |
+
return !empty( $sUser ) && in_array( $sUser, $opts->getSecurityAdminUsers() );
|
48 |
}
|
49 |
|
50 |
protected function preProcessOptions() {
|
51 |
+
/** @var SecurityAdmin\Options $opts */
|
52 |
+
$opts = $this->getOptions();
|
53 |
+
|
54 |
if ( $this->isValidSecAdminRequest() ) {
|
55 |
$this->setSecurityAdminStatusOnOff( true );
|
56 |
}
|
70 |
}
|
71 |
}
|
72 |
|
73 |
+
$this->setOpt( 'sec_admin_users', $this->verifySecAdminUsers( $opts->getSecurityAdminUsers() ) );
|
74 |
}
|
75 |
|
76 |
/**
|
81 |
private function verifySecAdminUsers( $aSecUsers ) {
|
82 |
$oDP = Services::Data();
|
83 |
$oWpUsers = Services::WpUsers();
|
84 |
+
/** @var SecurityAdmin\Options $opts */
|
85 |
+
$opts = $this->getOptions();
|
86 |
|
87 |
$aFiltered = [];
|
88 |
foreach ( $aSecUsers as $nCurrentKey => $sUsernameOrEmail ) {
|
104 |
// We now run a bit of a sanity check to ensure that the current user is
|
105 |
// not adding users here that aren't themselves without a key to still gain access
|
106 |
$oCurrent = $oWpUsers->getCurrentWpUser();
|
107 |
+
if ( !empty( $aFiltered ) && !$opts->hasSecurityPIN() && !in_array( $oCurrent->user_login, $aFiltered ) ) {
|
108 |
$aFiltered[] = $oCurrent->user_login;
|
109 |
}
|
110 |
|
164 |
* @return bool
|
165 |
*/
|
166 |
public function isEnabledSecurityAdmin() {
|
167 |
+
/** @var SecurityAdmin\Options $opts */
|
168 |
+
$opts = $this->getOptions();
|
169 |
return $this->isModOptEnabled() &&
|
170 |
+
( count( $opts->getSecurityAdminUsers() ) > 0 ||
|
171 |
+
( $opts->hasSecurityPIN() && $this->getSecAdminTimeout() > 0 )
|
172 |
);
|
173 |
}
|
174 |
|
199 |
$bValid = false;
|
200 |
$sReqKey = Services::Request()->post( 'sec_admin_key' );
|
201 |
if ( !empty( $sReqKey ) ) {
|
202 |
+
/** @var SecurityAdmin\Options $opts */
|
203 |
+
$opts = $this->getOptions();
|
204 |
+
$bValid = hash_equals( $opts->getSecurityPIN(), md5( $sReqKey ) );
|
205 |
if ( !$bValid ) {
|
206 |
$sEscaped = isset( $_POST[ 'sec_admin_key' ] ) ? $_POST[ 'sec_admin_key' ] : '';
|
207 |
if ( !empty( $sEscaped ) ) {
|
208 |
// Workaround for escaping of passwords
|
209 |
+
$bValid = hash_equals( $opts->getSecurityPIN(), md5( $sEscaped ) );
|
210 |
if ( $bValid ) {
|
211 |
$this->setOpt( 'admin_access_key', md5( $sReqKey ) );
|
212 |
}
|
229 |
}
|
230 |
|
231 |
/**
|
232 |
+
* @param string $key
|
233 |
* @return bool
|
234 |
*/
|
235 |
+
public function verifyAccessKey( $key ) {
|
236 |
+
/** @var SecurityAdmin\Options $opts */
|
237 |
+
$opts = $this->getOptions();
|
238 |
+
return !empty( $key ) && hash_equals( $opts->getSecurityPIN(), md5( $key ) );
|
239 |
}
|
240 |
|
241 |
/**
|
287 |
return $sLogoUrl;
|
288 |
}
|
289 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
/**
|
291 |
* @return bool
|
292 |
*/
|
293 |
public function isWlEnabled() {
|
294 |
+
/** @var SecurityAdmin\Options $opts */
|
295 |
+
$opts = $this->getOptions();
|
296 |
+
return $opts->isEnabledWhitelabel() && $this->isPremium();
|
297 |
}
|
298 |
|
299 |
/**
|
358 |
}
|
359 |
}
|
360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
/**
|
362 |
* This is the point where you would want to do any options verification
|
363 |
*/
|
364 |
protected function doPrePluginOptionsSave() {
|
365 |
+
/** @var SecurityAdmin\Options $opts */
|
366 |
+
$opts = $this->getOptions();
|
367 |
|
368 |
+
if ( hash_equals( $opts->getSecurityPIN(), self::HASH_DELETE ) ) {
|
369 |
+
$opts->clearSecurityAdminKey();
|
370 |
$this->setSecurityAdminStatusOnOff( false );
|
371 |
}
|
372 |
|
373 |
// Restricting Activate Plugins also means restricting the rest.
|
374 |
+
$aPluginsRestrictions = $opts->getAdminAccessArea_Plugins();
|
375 |
if ( in_array( 'activate_plugins', $aPluginsRestrictions ) ) {
|
376 |
+
$opts->setOpt(
|
377 |
'admin_access_restrict_plugins',
|
378 |
array_unique( array_merge( $aPluginsRestrictions, [
|
379 |
'install_plugins',
|
384 |
}
|
385 |
|
386 |
// Restricting Switch (Activate) Themes also means restricting the rest.
|
387 |
+
$aThemesRestrictions = $opts->getAdminAccessArea_Themes();
|
388 |
if ( in_array( 'switch_themes', $aThemesRestrictions ) && in_array( 'edit_theme_options', $aThemesRestrictions ) ) {
|
389 |
+
$opts->setOpt(
|
390 |
'admin_access_restrict_themes',
|
391 |
array_unique( array_merge( $aThemesRestrictions, [
|
392 |
'install_themes',
|
396 |
);
|
397 |
}
|
398 |
|
399 |
+
$aPostRestrictions = $opts->getAdminAccessArea_Posts();
|
400 |
if ( in_array( 'edit', $aPostRestrictions ) ) {
|
401 |
+
$opts->setOpt(
|
402 |
'admin_access_restrict_posts',
|
403 |
array_unique( array_merge( $aPostRestrictions, [ 'create', 'publish', 'delete' ] ) )
|
404 |
);
|
405 |
}
|
406 |
}
|
407 |
|
|
|
|
|
408 |
public function preDeactivatePlugin() {
|
409 |
if ( !$this->getCon()->isPluginAdmin() ) {
|
410 |
Services::WpGeneral()->wpDie(
|
src/features/audit_trail.php
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
class ICWP_WPSF_FeatureHandler_AuditTrail extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
@@ -107,78 +106,6 @@ class ICWP_WPSF_FeatureHandler_AuditTrail extends ICWP_WPSF_FeatureHandler_BaseW
|
|
107 |
return $aData;
|
108 |
}
|
109 |
|
110 |
-
/**
|
111 |
-
* @param array $aAllData
|
112 |
-
* @return array
|
113 |
-
*/
|
114 |
-
public function addInsightsConfigData( $aAllData ) {
|
115 |
-
/** @var AuditTrail\Options $oOpts */
|
116 |
-
$oOpts = $this->getOptions();
|
117 |
-
|
118 |
-
$aThis = [
|
119 |
-
'strings' => [
|
120 |
-
'title' => __( 'Activity Audit Log', 'wp-simple-firewall' ),
|
121 |
-
'sub' => __( 'Track Activity: What, Who, When, Where', 'wp-simple-firewall' ),
|
122 |
-
],
|
123 |
-
'key_opts' => [],
|
124 |
-
'href_options' => $this->getUrl_AdminPage()
|
125 |
-
];
|
126 |
-
|
127 |
-
if ( !$this->isModOptEnabled() ) {
|
128 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
129 |
-
}
|
130 |
-
else {
|
131 |
-
$aAudit = [];
|
132 |
-
$aNonAudit = [];
|
133 |
-
$oOpts->isAuditShield() ? $aAudit[] = 'Shield' : $aNonAudit[] = 'Shield';
|
134 |
-
$oOpts->isAuditUsers() ? $aAudit[] = __( 'users', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'users', 'wp-simple-firewall' );
|
135 |
-
$oOpts->isAuditPlugins() ? $aAudit[] = __( 'plugins', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'plugins', 'wp-simple-firewall' );
|
136 |
-
$oOpts->isAuditThemes() ? $aAudit[] = __( 'themes', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'themes', 'wp-simple-firewall' );
|
137 |
-
$oOpts->isAuditPosts() ? $aAudit[] = __( 'posts', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'posts', 'wp-simple-firewall' );
|
138 |
-
$oOpts->isAuditEmails() ? $aAudit[] = __( 'emails', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'emails', 'wp-simple-firewall' );
|
139 |
-
$oOpts->isAuditWp() ? $aAudit[] = 'WP' : $aNonAudit[] = 'WP';
|
140 |
-
|
141 |
-
if ( empty( $aNonAudit ) ) {
|
142 |
-
$aThis[ 'key_opts' ][ 'audit' ] = [
|
143 |
-
'name' => __( 'Audit Areas', 'wp-simple-firewall' ),
|
144 |
-
'enabled' => true,
|
145 |
-
'summary' => __( 'All important events on your site are being logged', 'wp-simple-firewall' ),
|
146 |
-
'weight' => 2,
|
147 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_enable_audit_contexts' ),
|
148 |
-
];
|
149 |
-
}
|
150 |
-
elseif ( empty( $aAudit ) ) {
|
151 |
-
$aThis[ 'key_opts' ][ 'audit' ] = [
|
152 |
-
'name' => __( 'Audit Areas', 'wp-simple-firewall' ),
|
153 |
-
'enabled' => false,
|
154 |
-
'summary' => sprintf( __( 'No areas are set to be audited: %s', 'wp-simple-firewall' ), implode( ', ', $aAudit ) ),
|
155 |
-
'weight' => 2,
|
156 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_enable_audit_contexts' ),
|
157 |
-
];
|
158 |
-
}
|
159 |
-
else {
|
160 |
-
$aThis[ 'key_opts' ][ 'nonaudit' ] = [
|
161 |
-
'name' => __( 'Audit Events', 'wp-simple-firewall' ),
|
162 |
-
'enabled' => false,
|
163 |
-
'summary' => sprintf( __( "Important events aren't being audited: %s", 'wp-simple-firewall' ), implode( ', ', $aNonAudit ) ),
|
164 |
-
'weight' => 2,
|
165 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_enable_audit_contexts' ),
|
166 |
-
];
|
167 |
-
}
|
168 |
-
|
169 |
-
$aThis[ 'key_opts' ][ 'length' ] = [
|
170 |
-
'name' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
171 |
-
'enabled' => true,
|
172 |
-
'summary' => sprintf( __( 'Maximum Audit Trail entries limited to %s', 'wp-simple-firewall' ), $oOpts->getMaxEntries() ),
|
173 |
-
'weight' => 0,
|
174 |
-
'href' => $this->getUrl_DirectLinkToOption( 'audit_trail_max_entries' ),
|
175 |
-
];
|
176 |
-
}
|
177 |
-
|
178 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
179 |
-
return $aAllData;
|
180 |
-
}
|
181 |
-
|
182 |
/**
|
183 |
* @return string
|
184 |
*/
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_AuditTrail extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
106 |
return $aData;
|
107 |
}
|
108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
/**
|
110 |
* @return string
|
111 |
*/
|
src/features/autoupdates.php
CHANGED
@@ -1,121 +1,9 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Autoupdates;
|
5 |
-
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
8 |
|
9 |
-
/**
|
10 |
-
* @param array $aAllNotices
|
11 |
-
* @return array
|
12 |
-
*/
|
13 |
-
public function addInsightsNoticeData( $aAllNotices ) {
|
14 |
-
/** @var Autoupdates\Options $oOpts */
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
|
17 |
-
$aNotices = [
|
18 |
-
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
19 |
-
'messages' => []
|
20 |
-
];
|
21 |
-
{ //really disabled?
|
22 |
-
$oWp = Services::WpGeneral();
|
23 |
-
if ( $this->isModOptEnabled() ) {
|
24 |
-
if ( $oOpts->isDisableAllAutoUpdates() && !$oWp->getWpAutomaticUpdater()->is_disabled() ) {
|
25 |
-
$aNotices[ 'messages' ][ 'disabled_auto' ] = [
|
26 |
-
'title' => 'Auto Updates Not Really Disabled',
|
27 |
-
'message' => __( 'Automatic Updates Are Not Disabled As Expected.', 'wp-simple-firewall' ),
|
28 |
-
'href' => $this->getUrl_DirectLinkToOption( 'enable_autoupdate_disable_all' ),
|
29 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
30 |
-
'rec' => sprintf( __( 'A plugin/theme other than %s is affecting your automatic update settings.', 'wp-simple-firewall' ), $this->getCon()
|
31 |
-
->getHumanName() )
|
32 |
-
];
|
33 |
-
}
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
$aNotices[ 'count' ] = count( $aNotices[ 'messages' ] );
|
38 |
-
|
39 |
-
$aAllNotices[ 'autoupdates' ] = $aNotices;
|
40 |
-
return $aAllNotices;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @param array $aAllData
|
45 |
-
* @return array
|
46 |
-
*/
|
47 |
-
public function addInsightsConfigData( $aAllData ) {
|
48 |
-
/** @var Autoupdates\Options $oOpts */
|
49 |
-
$oOpts = $this->getOptions();
|
50 |
-
|
51 |
-
$aThis = [
|
52 |
-
'strings' => [
|
53 |
-
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
54 |
-
'sub' => __( 'Control WordPress Automatic Updates', 'wp-simple-firewall' ),
|
55 |
-
],
|
56 |
-
'key_opts' => [],
|
57 |
-
'href_options' => $this->getUrl_AdminPage()
|
58 |
-
];
|
59 |
-
|
60 |
-
if ( !$this->isModOptEnabled() ) {
|
61 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
62 |
-
}
|
63 |
-
else {
|
64 |
-
|
65 |
-
$bAllDisabled = $oOpts->isDisableAllAutoUpdates();
|
66 |
-
if ( $bAllDisabled ) {
|
67 |
-
$aThis[ 'key_opts' ][ 'disabled' ] = [
|
68 |
-
'name' => __( 'Disabled All', 'wp-simple-firewall' ),
|
69 |
-
'enabled' => !$bAllDisabled,
|
70 |
-
'summary' => $bAllDisabled ?
|
71 |
-
__( 'All automatic updates on this site are disabled', 'wp-simple-firewall' )
|
72 |
-
: __( 'The automatic updates system is enabled', 'wp-simple-firewall' ),
|
73 |
-
'weight' => 2,
|
74 |
-
'href' => $this->getUrl_DirectLinkToOption( 'enable_autoupdate_disable_all' ),
|
75 |
-
];
|
76 |
-
}
|
77 |
-
else {
|
78 |
-
$bCanCore = Services::WpGeneral()->canCoreUpdateAutomatically();
|
79 |
-
$aThis[ 'key_opts' ][ 'core_minor' ] = [
|
80 |
-
'name' => __( 'Core Updates', 'wp-simple-firewall' ),
|
81 |
-
'enabled' => $bCanCore,
|
82 |
-
'summary' => $bCanCore ?
|
83 |
-
__( 'Minor WP Core updates will be installed automatically', 'wp-simple-firewall' )
|
84 |
-
: __( 'Minor WP Core updates will not be installed automatically', 'wp-simple-firewall' ),
|
85 |
-
'weight' => 2,
|
86 |
-
'href' => $this->getUrl_DirectLinkToOption( 'autoupdate_core' ),
|
87 |
-
];
|
88 |
-
|
89 |
-
$bHasDelay = $this->isModOptEnabled() && $oOpts->getDelayUpdatesPeriod();
|
90 |
-
$aThis[ 'key_opts' ][ 'delay' ] = [
|
91 |
-
'name' => __( 'Update Delay', 'wp-simple-firewall' ),
|
92 |
-
'enabled' => $bHasDelay,
|
93 |
-
'summary' => $bHasDelay ?
|
94 |
-
__( 'Automatic updates are applied after a short delay', 'wp-simple-firewall' )
|
95 |
-
: __( 'Automatic updates are applied immediately', 'wp-simple-firewall' ),
|
96 |
-
'weight' => 1,
|
97 |
-
'href' => $this->getUrl_DirectLinkToOption( 'update_delay' ),
|
98 |
-
];
|
99 |
-
|
100 |
-
$sName = $this->getCon()->getHumanName();
|
101 |
-
$bSelfAuto = $this->isModOptEnabled()
|
102 |
-
&& in_array( $oOpts->getSelfAutoUpdateOpt(), [ 'auto', 'immediate' ] );
|
103 |
-
$aThis[ 'key_opts' ][ 'self' ] = [
|
104 |
-
'name' => __( 'Self Auto-Update', 'wp-simple-firewall' ),
|
105 |
-
'enabled' => $bSelfAuto,
|
106 |
-
'summary' => $bSelfAuto ?
|
107 |
-
sprintf( __( '%s is automatically updated', 'wp-simple-firewall' ), $sName )
|
108 |
-
: sprintf( __( "%s isn't automatically updated", 'wp-simple-firewall' ), $sName ),
|
109 |
-
'weight' => 1,
|
110 |
-
'href' => $this->getUrl_DirectLinkToOption( 'autoupdate_plugin_self' ),
|
111 |
-
];
|
112 |
-
}
|
113 |
-
}
|
114 |
-
|
115 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
116 |
-
return $aAllData;
|
117 |
-
}
|
118 |
-
|
119 |
/**
|
120 |
* @return string
|
121 |
*/
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
|
|
4 |
|
5 |
class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
/**
|
8 |
* @return string
|
9 |
*/
|
src/features/base.php
CHANGED
@@ -50,6 +50,11 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
50 |
*/
|
51 |
private $oStrings;
|
52 |
|
|
|
|
|
|
|
|
|
|
|
53 |
/**
|
54 |
* @var Shield\Modules\Base\Options
|
55 |
*/
|
@@ -96,33 +101,29 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
96 |
* @param array $aModProps
|
97 |
*/
|
98 |
protected function setupHooks( $aModProps ) {
|
99 |
-
$
|
100 |
$nRunPriority = isset( $aModProps[ 'load_priority' ] ) ? $aModProps[ 'load_priority' ] : 100;
|
101 |
|
102 |
-
add_action( $
|
103 |
$this->onModulesLoaded();
|
104 |
}, $nRunPriority );
|
105 |
-
add_action( $
|
106 |
add_action( 'init', [ $this, 'onWpInit' ], 1 );
|
107 |
|
108 |
$nMenuPri = isset( $aModProps[ 'menu_priority' ] ) ? $aModProps[ 'menu_priority' ] : 100;
|
109 |
-
add_filter( $
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
add_filter( $
|
114 |
-
add_action( $oCon->prefix( 'plugin_shutdown' ), [ $this, 'onPluginShutdown' ] );
|
115 |
-
add_action( $oCon->prefix( 'deactivate_plugin' ), [ $this, 'onPluginDeactivate' ] );
|
116 |
-
add_action( $oCon->prefix( 'delete_plugin' ), [ $this, 'onPluginDelete' ] );
|
117 |
-
add_filter( $oCon->prefix( 'aggregate_all_plugin_options' ), [ $this, 'aggregateOptionsValues' ] );
|
118 |
|
119 |
-
add_filter( $
|
120 |
|
121 |
-
add_action( $
|
122 |
-
add_action( $
|
123 |
|
124 |
// supply supported events for this module
|
125 |
-
add_filter( $
|
126 |
return array_merge(
|
127 |
is_array( $aEvents ) ? $aEvents : [],
|
128 |
array_map(
|
@@ -217,8 +218,8 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
217 |
* @return string[]
|
218 |
*/
|
219 |
private function getAllDbClasses() {
|
220 |
-
$
|
221 |
-
return is_array( $
|
222 |
}
|
223 |
|
224 |
/**
|
@@ -331,11 +332,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
331 |
$this->getProcessor()->execute();
|
332 |
}
|
333 |
|
334 |
-
/**
|
335 |
-
* A action added to WordPress 'init' hook
|
336 |
-
*/
|
337 |
public function onWpInit() {
|
338 |
-
$oReq = Services::Request();
|
339 |
|
340 |
$sShieldAction = $this->getCon()->getShieldAction();
|
341 |
if ( !empty( $sShieldAction ) ) {
|
@@ -360,7 +357,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
360 |
else {
|
361 |
try {
|
362 |
if ( $this->verifyModActionRequest() ) {
|
363 |
-
$this->handleModAction(
|
364 |
}
|
365 |
}
|
366 |
catch ( \Exception $oE ) {
|
@@ -496,14 +493,14 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
496 |
* @return array
|
497 |
*/
|
498 |
protected function getModActionParams( $sAction ) {
|
499 |
-
$
|
500 |
return [
|
501 |
-
'action' => $
|
502 |
'exec' => $sAction,
|
503 |
'mod_slug' => $this->getModSlug(),
|
504 |
'ts' => Services::Request()->ts(),
|
505 |
'exec_nonce' => substr(
|
506 |
-
hash_hmac( 'md5', $sAction.Services::Request()->ts(), $
|
507 |
, 0, 6 )
|
508 |
];
|
509 |
}
|
@@ -593,7 +590,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
593 |
* @return bool
|
594 |
*/
|
595 |
public function isModuleEnabled() {
|
596 |
-
$oOpts = $this->getOptions();
|
597 |
/** @var Shield\Modules\Plugin\Options $oPluginOpts */
|
598 |
$oPluginOpts = $this->getCon()->getModule_Plugin()->getOptions();
|
599 |
|
@@ -607,7 +603,8 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
607 |
elseif ( $this->getCon()->getIfForceOffActive() ) {
|
608 |
$bEnabled = false;
|
609 |
}
|
610 |
-
elseif ( $
|
|
|
611 |
$bEnabled = false;
|
612 |
}
|
613 |
else {
|
@@ -628,7 +625,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
628 |
/**
|
629 |
* @return string
|
630 |
*/
|
631 |
-
|
632 |
return 'enable_'.$this->getSlug();
|
633 |
}
|
634 |
|
@@ -660,7 +657,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
660 |
/**
|
661 |
* @param array $aItems
|
662 |
* @return array
|
663 |
-
* @deprecated 9.0
|
664 |
*/
|
665 |
public function addAdminMenuBarItems( array $aItems ) {
|
666 |
return $aItems;
|
@@ -740,38 +737,33 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
740 |
/**
|
741 |
* @param array $aSummaryData
|
742 |
* @return array
|
|
|
743 |
*/
|
744 |
public function addModuleSummaryData( $aSummaryData ) {
|
745 |
-
if ( $this->getIfShowModuleLink() ) {
|
746 |
-
$aSummaryData[ $this->getModSlug( false ) ] = $this->buildSummaryData();
|
747 |
-
}
|
748 |
return $aSummaryData;
|
749 |
}
|
750 |
|
751 |
/**
|
752 |
-
*
|
753 |
-
* @return array
|
754 |
-
*/
|
755 |
-
public function addInsightsNoticeData( $aAllNotices ) {
|
756 |
-
return $aAllNotices;
|
757 |
-
}
|
758 |
-
|
759 |
-
/**
|
760 |
-
* @param array $aAllData
|
761 |
-
* @return array
|
762 |
*/
|
763 |
-
public function
|
764 |
-
return
|
|
|
|
|
|
|
|
|
|
|
765 |
}
|
766 |
|
767 |
/**
|
768 |
* @return array
|
769 |
*/
|
770 |
-
|
771 |
-
$
|
772 |
-
$sMenuTitle = $
|
773 |
|
774 |
-
$aSections = $
|
775 |
foreach ( $aSections as $sSlug => $aSection ) {
|
776 |
try {
|
777 |
$aStrings = $this->getStrings()->getSectionStrings( $aSection[ 'slug' ] );
|
@@ -780,29 +772,30 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
780 |
$aSection[ $sKey ] = $sVal;
|
781 |
}
|
782 |
}
|
783 |
-
catch ( \Exception $
|
784 |
}
|
785 |
}
|
786 |
|
787 |
$aSum = [
|
788 |
-
'
|
789 |
-
'
|
790 |
-
'
|
791 |
-
'name'
|
792 |
-
'sidebar_name'
|
793 |
-
'menu_title'
|
794 |
-
'href'
|
795 |
-
'sections'
|
796 |
-
'options'
|
|
|
797 |
];
|
798 |
|
799 |
-
foreach ( $
|
800 |
try {
|
801 |
$aOptData = $this->getStrings()->getOptionStrings( $sOptKey );
|
802 |
$aOptData[ 'href' ] = $this->getUrl_DirectLinkToOption( $sOptKey );
|
803 |
$aSum[ 'options' ][ $sOptKey ] = $aOptData;
|
804 |
}
|
805 |
-
catch ( \Exception $
|
806 |
}
|
807 |
}
|
808 |
|
@@ -814,31 +807,43 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
814 |
}
|
815 |
|
816 |
/**
|
817 |
-
* @
|
|
|
|
|
818 |
*/
|
819 |
-
|
820 |
-
return $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
821 |
}
|
822 |
|
823 |
/**
|
824 |
* @return bool
|
|
|
825 |
*/
|
826 |
-
public function
|
827 |
-
return
|
828 |
}
|
829 |
|
830 |
/**
|
831 |
* @return bool
|
832 |
*/
|
833 |
-
public function
|
834 |
-
return (bool)$this->getOptions()->getFeatureProperty( '
|
835 |
}
|
836 |
|
837 |
/**
|
838 |
* @return bool
|
839 |
*/
|
840 |
-
public function
|
841 |
-
return $this->getOptions()->getFeatureProperty( '
|
842 |
}
|
843 |
|
844 |
/**
|
@@ -936,7 +941,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
936 |
|
937 |
/**
|
938 |
* Sets the value for the given option key
|
939 |
-
* Note: We also set the ability to bypass admin access since setOpt() is a protected function
|
940 |
* @param string $sOptionKey
|
941 |
* @param mixed $mValue
|
942 |
* @return $this
|
@@ -1076,154 +1080,19 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1076 |
* It doesn't set any values, just populates the array created in buildOptions()
|
1077 |
* with values stored.
|
1078 |
* It has to handle the conversion of stored values to data to be displayed to the user.
|
|
|
1079 |
*/
|
1080 |
public function buildOptions() {
|
1081 |
-
|
1082 |
-
$bPremiumEnabled = $this->getCon()->isPremiumExtensionsEnabled();
|
1083 |
-
|
1084 |
-
$oOptsVo = $this->getOptions();
|
1085 |
-
$aOptions = $oOptsVo->getOptionsForPluginUse();
|
1086 |
-
|
1087 |
-
foreach ( $aOptions as $nSectionKey => $aSection ) {
|
1088 |
-
|
1089 |
-
if ( !empty( $aSection[ 'options' ] ) ) {
|
1090 |
-
|
1091 |
-
foreach ( $aSection[ 'options' ] as $nKey => $aOption ) {
|
1092 |
-
$aOption[ 'is_value_default' ] = ( $aOption[ 'value' ] === $aOption[ 'default' ] );
|
1093 |
-
$bIsPrem = isset( $aOption[ 'premium' ] ) && $aOption[ 'premium' ];
|
1094 |
-
if ( !$bIsPrem || $bPremiumEnabled ) {
|
1095 |
-
$aSection[ 'options' ][ $nKey ] = $this->buildOptionForUi( $aOption );
|
1096 |
-
}
|
1097 |
-
else {
|
1098 |
-
unset( $aSection[ 'options' ][ $nKey ] );
|
1099 |
-
}
|
1100 |
-
}
|
1101 |
-
|
1102 |
-
if ( empty( $aSection[ 'options' ] ) ) {
|
1103 |
-
unset( $aOptions[ $nSectionKey ] );
|
1104 |
-
}
|
1105 |
-
else {
|
1106 |
-
try {
|
1107 |
-
$aStrings = $this->getStrings()->getSectionStrings( $aSection[ 'slug' ] );
|
1108 |
-
foreach ( $aStrings as $sKey => $sVal ) {
|
1109 |
-
unset( $aSection[ $sKey ] );
|
1110 |
-
$aSection[ $sKey ] = $sVal;
|
1111 |
-
}
|
1112 |
-
}
|
1113 |
-
catch ( \Exception $oE ) {
|
1114 |
-
}
|
1115 |
-
$aOptions[ $nSectionKey ] = $aSection;
|
1116 |
-
}
|
1117 |
-
|
1118 |
-
$aWarnings = [];
|
1119 |
-
if ( !$oOptsVo->isSectionReqsMet( $aSection[ 'slug' ] ) ) {
|
1120 |
-
$aWarnings[] = __( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.', 'wp-simple-firewall' );
|
1121 |
-
}
|
1122 |
-
$aOptions[ $nSectionKey ][ 'warnings' ] = array_merge(
|
1123 |
-
$aWarnings,
|
1124 |
-
$this->getSectionWarnings( $aSection[ 'slug' ] )
|
1125 |
-
);
|
1126 |
-
$aOptions[ $nSectionKey ][ 'notices' ] = $this->getSectionNotices( $aSection[ 'slug' ] );
|
1127 |
-
|
1128 |
-
if ( !empty( $aSection[ 'help_video_id' ] ) ) {
|
1129 |
-
$sHelpVideoUrl = $this->getHelpVideoUrl( $aSection[ 'help_video_id' ] );
|
1130 |
-
}
|
1131 |
-
else {
|
1132 |
-
$sHelpVideoUrl = '';
|
1133 |
-
}
|
1134 |
-
$aOptions[ $nSectionKey ][ 'help_video_url' ] = ''; /* Remove on Shield 9.0 */
|
1135 |
-
}
|
1136 |
-
}
|
1137 |
-
|
1138 |
-
return $aOptions;
|
1139 |
-
}
|
1140 |
-
|
1141 |
-
/**
|
1142 |
-
* @param string $sSectionSlug
|
1143 |
-
* @return array
|
1144 |
-
*/
|
1145 |
-
protected function getSectionNotices( $sSectionSlug ) {
|
1146 |
-
return [];
|
1147 |
-
}
|
1148 |
-
|
1149 |
-
/**
|
1150 |
-
* @param string $sSection
|
1151 |
-
* @return array
|
1152 |
-
*/
|
1153 |
-
protected function getSectionWarnings( $sSection ) {
|
1154 |
-
return [];
|
1155 |
}
|
1156 |
|
1157 |
/**
|
1158 |
* @param array $aOptParams
|
1159 |
* @return array
|
|
|
1160 |
*/
|
1161 |
protected function buildOptionForUi( $aOptParams ) {
|
1162 |
-
|
1163 |
-
$mCurrent = $aOptParams[ 'value' ];
|
1164 |
-
|
1165 |
-
switch ( $aOptParams[ 'type' ] ) {
|
1166 |
-
|
1167 |
-
case 'password':
|
1168 |
-
if ( !empty( $mCurrent ) ) {
|
1169 |
-
$mCurrent = '';
|
1170 |
-
}
|
1171 |
-
break;
|
1172 |
-
|
1173 |
-
case 'array':
|
1174 |
-
|
1175 |
-
if ( empty( $mCurrent ) || !is_array( $mCurrent ) ) {
|
1176 |
-
$mCurrent = [];
|
1177 |
-
}
|
1178 |
-
|
1179 |
-
$aOptParams[ 'rows' ] = count( $mCurrent ) + 2;
|
1180 |
-
$mCurrent = stripslashes( implode( "\n", $mCurrent ) );
|
1181 |
-
|
1182 |
-
break;
|
1183 |
-
|
1184 |
-
case 'comma_separated_lists':
|
1185 |
-
|
1186 |
-
$aNewValues = [];
|
1187 |
-
if ( !empty( $mCurrent ) && is_array( $mCurrent ) ) {
|
1188 |
-
|
1189 |
-
foreach ( $mCurrent as $sPage => $aParams ) {
|
1190 |
-
$aNewValues[] = $sPage.', '.implode( ", ", $aParams );
|
1191 |
-
}
|
1192 |
-
}
|
1193 |
-
$aOptParams[ 'rows' ] = count( $aNewValues ) + 1;
|
1194 |
-
$mCurrent = implode( "\n", $aNewValues );
|
1195 |
-
|
1196 |
-
break;
|
1197 |
-
|
1198 |
-
case 'multiple_select':
|
1199 |
-
if ( !is_array( $mCurrent ) ) {
|
1200 |
-
$mCurrent = [];
|
1201 |
-
}
|
1202 |
-
break;
|
1203 |
-
|
1204 |
-
case 'text':
|
1205 |
-
$mCurrent = stripslashes( $this->getTextOpt( $aOptParams[ 'key' ] ) );
|
1206 |
-
break;
|
1207 |
-
}
|
1208 |
-
|
1209 |
-
$aParams = [
|
1210 |
-
'value' => is_scalar( $mCurrent ) ? esc_attr( $mCurrent ) : $mCurrent,
|
1211 |
-
'disabled' => !$this->isPremium() && ( isset( $aOptParams[ 'premium' ] ) && $aOptParams[ 'premium' ] ),
|
1212 |
-
];
|
1213 |
-
$aParams[ 'enabled' ] = !$aParams[ 'disabled' ];
|
1214 |
-
$aOptParams = array_merge( [ 'rows' => 2 ], $aOptParams, $aParams );
|
1215 |
-
|
1216 |
-
// add strings
|
1217 |
-
try {
|
1218 |
-
$aOptStrings = $this->getStrings()->getOptionStrings( $aOptParams[ 'key' ] );
|
1219 |
-
if ( is_array( $aOptStrings[ 'description' ] ) ) {
|
1220 |
-
$aOptStrings[ 'description' ] = implode( "<br/>", $aOptStrings[ 'description' ] );
|
1221 |
-
}
|
1222 |
-
$aOptParams = Services::DataManipulation()->mergeArraysRecursive( $aOptParams, $aOptStrings );
|
1223 |
-
}
|
1224 |
-
catch ( \Exception $oE ) {
|
1225 |
-
}
|
1226 |
-
return $aOptParams;
|
1227 |
}
|
1228 |
|
1229 |
/**
|
@@ -1250,7 +1119,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1250 |
protected function getAllFormOptionsAndTypes() {
|
1251 |
$aOpts = [];
|
1252 |
|
1253 |
-
foreach ( $this->buildOptions() as $aOptionsSection ) {
|
1254 |
if ( !empty( $aOptionsSection ) ) {
|
1255 |
foreach ( $aOptionsSection[ 'options' ] as $aOption ) {
|
1256 |
$aOpts[ $aOption[ 'key' ] ] = $aOption[ 'type' ];
|
@@ -1463,118 +1332,25 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1463 |
* @return string
|
1464 |
*/
|
1465 |
protected function renderModulePage( $aData = [] ) {
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
return $this->renderTemplate( 'index.php', $aData );
|
1472 |
}
|
1473 |
|
1474 |
/**
|
1475 |
* @return array
|
|
|
1476 |
*/
|
1477 |
public function getBaseDisplayData() {
|
1478 |
-
|
1479 |
-
|
1480 |
-
/** @var Shield\Modules\Plugin\Options $oPluginOptions */
|
1481 |
-
$oPluginOptions = $oCon->getModule_Plugin()
|
1482 |
-
->getOptions();
|
1483 |
-
|
1484 |
-
return [
|
1485 |
-
'sPluginName' => $oCon->getHumanName(),
|
1486 |
-
'sTagline' => $this->getOptions()->getFeatureTagline(),
|
1487 |
-
'nonce_field' => wp_nonce_field( $oCon->getPluginPrefix(), '_wpnonce', true, false ), //don't echo!
|
1488 |
-
'form_action' => 'admin.php?page='.$this->getModSlug(),
|
1489 |
-
'aPluginLabels' => $oCon->getLabels(),
|
1490 |
-
'help_video' => [
|
1491 |
-
'auto_show' => $this->getIfAutoShowHelpVideo(),
|
1492 |
-
'iframe_url' => $this->getHelpVideoUrl( $this->getHelpVideoId() ),
|
1493 |
-
'display_id' => 'ShieldHelpVideo'.$this->getSlug(),
|
1494 |
-
'options' => $this->getHelpVideoOptions(),
|
1495 |
-
'displayable' => $this->isHelpVideoDisplayable(),
|
1496 |
-
'show' => $this->isHelpVideoDisplayable() && !$this->getHelpVideoHasBeenClosed(),
|
1497 |
-
'width' => 772,
|
1498 |
-
'height' => 454,
|
1499 |
-
],
|
1500 |
-
'aSummaryData' => $this->getModulesSummaryData(),
|
1501 |
-
|
1502 |
-
// 'sPageTitle' => sprintf( '%s: %s', $oCon->getHumanName(), $this->getMainFeatureName() ),
|
1503 |
-
'sPageTitle' => $this->getMainFeatureName(),
|
1504 |
-
'data' => [
|
1505 |
-
'mod_slug' => $this->getModSlug( true ),
|
1506 |
-
'mod_slug_short' => $this->getModSlug( false ),
|
1507 |
-
'all_options' => $this->buildOptions(),
|
1508 |
-
'xferable_opts' => ( new Shield\Modules\Plugin\Lib\ImportExport\Options\BuildTransferableOptions() )
|
1509 |
-
->setMod( $this )
|
1510 |
-
->build(),
|
1511 |
-
'hidden_options' => $this->getOptions()->getHiddenOptions()
|
1512 |
-
],
|
1513 |
-
'ajax' => [
|
1514 |
-
'mod_options' => $this->getAjaxActionData( 'mod_options' ),
|
1515 |
-
],
|
1516 |
-
'vendors' => [
|
1517 |
-
'widget_freshdesk' => '3000000081' /* TODO: plugin spec config */
|
1518 |
-
],
|
1519 |
-
'strings' => $this->getStrings()->getDisplayStrings(),
|
1520 |
-
'flags' => [
|
1521 |
-
'access_restricted' => !$this->canDisplayOptionsForm(),
|
1522 |
-
'show_ads' => $this->getIsShowMarketing(),
|
1523 |
-
'wrap_page_content' => true,
|
1524 |
-
'show_standard_options' => true,
|
1525 |
-
'show_content_help' => true,
|
1526 |
-
'show_alt_content' => false,
|
1527 |
-
'has_wizard' => $this->hasWizard(),
|
1528 |
-
'is_premium' => $this->isPremium(),
|
1529 |
-
'show_transfer_switch' => $this->isPremium(),
|
1530 |
-
'is_wpcli' => $oPluginOptions->isEnabledWpcli()
|
1531 |
-
],
|
1532 |
-
'hrefs' => [
|
1533 |
-
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
1534 |
-
'goprofooter' => 'https://shsec.io/goprofooter',
|
1535 |
-
'wizard_link' => $this->getUrl_WizardLanding(),
|
1536 |
-
'wizard_landing' => $this->getUrl_WizardLanding(),
|
1537 |
-
|
1538 |
-
'form_action' => Services::Request()->getUri(),
|
1539 |
-
'css_bootstrap' => $oCon->getPluginUrl_Css( 'bootstrap4.min' ),
|
1540 |
-
'css_pages' => $oCon->getPluginUrl_Css( 'pages' ),
|
1541 |
-
'css_steps' => $oCon->getPluginUrl_Css( 'jquery.steps' ),
|
1542 |
-
'css_fancybox' => $oCon->getPluginUrl_Css( 'jquery.fancybox.min' ),
|
1543 |
-
'css_globalplugin' => $oCon->getPluginUrl_Css( 'global-plugin' ),
|
1544 |
-
'css_wizard' => $oCon->getPluginUrl_Css( 'wizard' ),
|
1545 |
-
'js_jquery' => Services::Includes()->getUrl_Jquery(),
|
1546 |
-
'js_bootstrap' => $oCon->getPluginUrl_Js( 'bootstrap4.bundle.min' ),
|
1547 |
-
'js_fancybox' => $oCon->getPluginUrl_Js( 'jquery.fancybox.min' ),
|
1548 |
-
'js_globalplugin' => $oCon->getPluginUrl_Js( 'global-plugin' ),
|
1549 |
-
'js_steps' => $oCon->getPluginUrl_Js( 'jquery.steps.min' ),
|
1550 |
-
'js_wizard' => $oCon->getPluginUrl_Js( 'wizard' ),
|
1551 |
-
],
|
1552 |
-
'imgs' => [
|
1553 |
-
'favicon' => $oCon->getPluginUrl_Image( 'pluginlogo_24x24.png' ),
|
1554 |
-
'plugin_banner' => $oCon->getPluginUrl_Image( 'banner-1500x500-transparent.png' ),
|
1555 |
-
],
|
1556 |
-
'content' => [
|
1557 |
-
'options_form' => '',
|
1558 |
-
'alt' => '',
|
1559 |
-
'actions' => '',
|
1560 |
-
'help' => '',
|
1561 |
-
'wizard_landing' => ''
|
1562 |
-
]
|
1563 |
-
];
|
1564 |
-
}
|
1565 |
-
|
1566 |
-
/**
|
1567 |
-
* @return string
|
1568 |
-
*/
|
1569 |
-
protected function getContentHelp() {
|
1570 |
-
return $this->renderTemplate( 'snippets/module-help-template.php', $this->getBaseDisplayData() );
|
1571 |
}
|
1572 |
|
1573 |
/**
|
1574 |
* @return string
|
1575 |
*/
|
1576 |
protected function getContentWizardLanding() {
|
1577 |
-
$aData = $this->getBaseDisplayData();
|
1578 |
if ( $this->hasWizard() ) {
|
1579 |
$aData[ 'content' ][ 'wizard_landing' ] = $this->getWizardHandler()->renderWizardLandingSnippet();
|
1580 |
}
|
@@ -1601,13 +1377,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1601 |
);
|
1602 |
}
|
1603 |
|
1604 |
-
/**
|
1605 |
-
* @return array[]
|
1606 |
-
*/
|
1607 |
-
protected function getModulesSummaryData() {
|
1608 |
-
return apply_filters( $this->prefix( 'collect_mod_summary' ), [] );
|
1609 |
-
}
|
1610 |
-
|
1611 |
/**
|
1612 |
* @param string $sWizardSlug
|
1613 |
* @return string
|
@@ -1636,7 +1405,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1636 |
/**
|
1637 |
* @return string
|
1638 |
*/
|
1639 |
-
|
1640 |
return $this->getUrl_Wizard( 'landing' );
|
1641 |
}
|
1642 |
|
@@ -1680,7 +1449,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1680 |
/**
|
1681 |
* @return bool
|
1682 |
*/
|
1683 |
-
|
1684 |
return apply_filters( $this->prefix( 'show_marketing' ), !$this->isPremium() );
|
1685 |
}
|
1686 |
|
@@ -1700,7 +1469,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1700 |
return $this->getCon()
|
1701 |
->getRenderer()
|
1702 |
->setTemplate( $sTemplate )
|
1703 |
-
->setRenderVars( $this->getBaseDisplayData() )
|
1704 |
->setTemplateEngineTwig()
|
1705 |
->render();
|
1706 |
}
|
@@ -1712,7 +1481,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1712 |
/**
|
1713 |
* @return bool
|
1714 |
*/
|
1715 |
-
|
1716 |
return $this->getOptions()->isAccessRestricted() ? $this->getCon()->isPluginAdmin() : true;
|
1717 |
}
|
1718 |
|
@@ -1865,80 +1634,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1865 |
return $aData;
|
1866 |
}
|
1867 |
|
1868 |
-
protected function getHelpVideoOptions() {
|
1869 |
-
$aOptions = $this->getOpt( 'help_video_options', [] );
|
1870 |
-
if ( is_null( $aOptions ) || !is_array( $aOptions ) ) {
|
1871 |
-
$aOptions = [
|
1872 |
-
'closed' => false,
|
1873 |
-
'displayed' => false,
|
1874 |
-
'played' => false,
|
1875 |
-
];
|
1876 |
-
$this->setOpt( 'help_video_options', $aOptions );
|
1877 |
-
}
|
1878 |
-
return $aOptions;
|
1879 |
-
}
|
1880 |
-
|
1881 |
-
/**
|
1882 |
-
* @return bool
|
1883 |
-
*/
|
1884 |
-
protected function getHelpVideoHasBeenClosed() {
|
1885 |
-
return (bool)$this->getHelpVideoOption( 'closed' );
|
1886 |
-
}
|
1887 |
-
|
1888 |
-
/**
|
1889 |
-
* @return bool
|
1890 |
-
*/
|
1891 |
-
protected function getHelpVideoHasBeenDisplayed() {
|
1892 |
-
return (bool)$this->getHelpVideoOption( 'displayed' );
|
1893 |
-
}
|
1894 |
-
|
1895 |
-
/**
|
1896 |
-
* @return bool
|
1897 |
-
*/
|
1898 |
-
protected function getVideoHasBeenPlayed() {
|
1899 |
-
return (bool)$this->getHelpVideoOption( 'played' );
|
1900 |
-
}
|
1901 |
-
|
1902 |
-
/**
|
1903 |
-
* @param string $sKey
|
1904 |
-
* @return mixed|null
|
1905 |
-
*/
|
1906 |
-
protected function getHelpVideoOption( $sKey ) {
|
1907 |
-
$aOpts = $this->getHelpVideoOptions();
|
1908 |
-
return isset( $aOpts[ $sKey ] ) ? $aOpts[ $sKey ] : null;
|
1909 |
-
}
|
1910 |
-
|
1911 |
-
/**
|
1912 |
-
* @return bool
|
1913 |
-
*/
|
1914 |
-
protected function getIfAutoShowHelpVideo() {
|
1915 |
-
return !$this->getHelpVideoHasBeenClosed();
|
1916 |
-
}
|
1917 |
-
|
1918 |
-
/**
|
1919 |
-
* @return string
|
1920 |
-
*/
|
1921 |
-
protected function getHelpVideoId() {
|
1922 |
-
return $this->getDef( 'help_video_id' );
|
1923 |
-
}
|
1924 |
-
|
1925 |
-
/**
|
1926 |
-
* @param string $sId
|
1927 |
-
* @return string
|
1928 |
-
*/
|
1929 |
-
protected function getHelpVideoUrl( $sId ) {
|
1930 |
-
return sprintf( 'https://player.vimeo.com/video/%s', $sId );
|
1931 |
-
}
|
1932 |
-
|
1933 |
-
/**
|
1934 |
-
* @return bool
|
1935 |
-
*/
|
1936 |
-
protected function isHelpVideoDisplayable() {
|
1937 |
-
$sId = $this->getHelpVideoId();
|
1938 |
-
return false;
|
1939 |
-
return !empty( $sId );
|
1940 |
-
}
|
1941 |
-
|
1942 |
/**
|
1943 |
* @return null|Shield\Modules\Base\ShieldOptions|mixed
|
1944 |
*/
|
@@ -1972,15 +1667,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1972 |
return $this->oWpCli;
|
1973 |
}
|
1974 |
|
1975 |
-
/**
|
1976 |
-
* The primary DB for the
|
1977 |
-
* @return null|Shield\Databases\Base\Handler|mixed
|
1978 |
-
*/
|
1979 |
-
public function getPrimaryDbHandler() {
|
1980 |
-
$aDBs = $this->getAllDbClasses();
|
1981 |
-
return empty( $aDBs ) ? null : $this->getDbH( key( $aDBs ) );
|
1982 |
-
}
|
1983 |
-
|
1984 |
/**
|
1985 |
* @return null|Shield\Modules\Base\Strings
|
1986 |
*/
|
@@ -1991,6 +1677,21 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
1991 |
return $this->oStrings;
|
1992 |
}
|
1993 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1994 |
/**
|
1995 |
* @return Shield\Modules\Base\BaseReporting|mixed|false
|
1996 |
*/
|
@@ -2095,14 +1796,4 @@ abstract class ICWP_WPSF_FeatureHandler_Base {
|
|
2095 |
protected function doExtraSubmitProcessing() {
|
2096 |
$this->preProcessOptions();
|
2097 |
}
|
2098 |
-
|
2099 |
-
/**
|
2100 |
-
* @deprecated 9.0.5
|
2101 |
-
*/
|
2102 |
-
protected function updateHandler() {
|
2103 |
-
$oH = $this->getUpgradeHandler();
|
2104 |
-
if ( $oH instanceof Shield\Modules\Base\Upgrade ) {
|
2105 |
-
$oH->setMod( $this )->execute();
|
2106 |
-
}
|
2107 |
-
}
|
2108 |
}
|
50 |
*/
|
51 |
private $oStrings;
|
52 |
|
53 |
+
/**
|
54 |
+
* @var Shield\Modules\Base\UI
|
55 |
+
*/
|
56 |
+
private $oUI;
|
57 |
+
|
58 |
/**
|
59 |
* @var Shield\Modules\Base\Options
|
60 |
*/
|
101 |
* @param array $aModProps
|
102 |
*/
|
103 |
protected function setupHooks( $aModProps ) {
|
104 |
+
$con = $this->getCon();
|
105 |
$nRunPriority = isset( $aModProps[ 'load_priority' ] ) ? $aModProps[ 'load_priority' ] : 100;
|
106 |
|
107 |
+
add_action( $con->prefix( 'modules_loaded' ), function () {
|
108 |
$this->onModulesLoaded();
|
109 |
}, $nRunPriority );
|
110 |
+
add_action( $con->prefix( 'run_processors' ), [ $this, 'onRunProcessors' ], $nRunPriority );
|
111 |
add_action( 'init', [ $this, 'onWpInit' ], 1 );
|
112 |
|
113 |
$nMenuPri = isset( $aModProps[ 'menu_priority' ] ) ? $aModProps[ 'menu_priority' ] : 100;
|
114 |
+
add_filter( $con->prefix( 'submenu_items' ), [ $this, 'supplySubMenuItem' ], $nMenuPri );
|
115 |
+
add_action( $con->prefix( 'plugin_shutdown' ), [ $this, 'onPluginShutdown' ] );
|
116 |
+
add_action( $con->prefix( 'deactivate_plugin' ), [ $this, 'onPluginDeactivate' ] );
|
117 |
+
add_action( $con->prefix( 'delete_plugin' ), [ $this, 'onPluginDelete' ] );
|
118 |
+
add_filter( $con->prefix( 'aggregate_all_plugin_options' ), [ $this, 'aggregateOptionsValues' ] );
|
|
|
|
|
|
|
|
|
119 |
|
120 |
+
add_filter( $con->prefix( 'register_admin_notices' ), [ $this, 'fRegisterAdminNotices' ] );
|
121 |
|
122 |
+
add_action( $con->prefix( 'daily_cron' ), [ $this, 'runDailyCron' ] );
|
123 |
+
add_action( $con->prefix( 'hourly_cron' ), [ $this, 'runHourlyCron' ] );
|
124 |
|
125 |
// supply supported events for this module
|
126 |
+
add_filter( $con->prefix( 'get_all_events' ), function ( $aEvents ) {
|
127 |
return array_merge(
|
128 |
is_array( $aEvents ) ? $aEvents : [],
|
129 |
array_map(
|
218 |
* @return string[]
|
219 |
*/
|
220 |
private function getAllDbClasses() {
|
221 |
+
$classes = $this->getOptions()->getDef( 'db_classes' );
|
222 |
+
return is_array( $classes ) ? $classes : [];
|
223 |
}
|
224 |
|
225 |
/**
|
332 |
$this->getProcessor()->execute();
|
333 |
}
|
334 |
|
|
|
|
|
|
|
335 |
public function onWpInit() {
|
|
|
336 |
|
337 |
$sShieldAction = $this->getCon()->getShieldAction();
|
338 |
if ( !empty( $sShieldAction ) ) {
|
357 |
else {
|
358 |
try {
|
359 |
if ( $this->verifyModActionRequest() ) {
|
360 |
+
$this->handleModAction( Services::Request()->request( 'exec' ) );
|
361 |
}
|
362 |
}
|
363 |
catch ( \Exception $oE ) {
|
493 |
* @return array
|
494 |
*/
|
495 |
protected function getModActionParams( $sAction ) {
|
496 |
+
$con = $this->getCon();
|
497 |
return [
|
498 |
+
'action' => $con->prefix(),
|
499 |
'exec' => $sAction,
|
500 |
'mod_slug' => $this->getModSlug(),
|
501 |
'ts' => Services::Request()->ts(),
|
502 |
'exec_nonce' => substr(
|
503 |
+
hash_hmac( 'md5', $sAction.Services::Request()->ts(), $con->getSiteInstallationId() )
|
504 |
, 0, 6 )
|
505 |
];
|
506 |
}
|
590 |
* @return bool
|
591 |
*/
|
592 |
public function isModuleEnabled() {
|
|
|
593 |
/** @var Shield\Modules\Plugin\Options $oPluginOpts */
|
594 |
$oPluginOpts = $this->getCon()->getModule_Plugin()->getOptions();
|
595 |
|
603 |
elseif ( $this->getCon()->getIfForceOffActive() ) {
|
604 |
$bEnabled = false;
|
605 |
}
|
606 |
+
elseif ( $this->getOptions()->getFeatureProperty( 'premium' ) === true
|
607 |
+
&& !$this->isPremium() ) {
|
608 |
$bEnabled = false;
|
609 |
}
|
610 |
else {
|
625 |
/**
|
626 |
* @return string
|
627 |
*/
|
628 |
+
public function getEnableModOptKey() {
|
629 |
return 'enable_'.$this->getSlug();
|
630 |
}
|
631 |
|
657 |
/**
|
658 |
* @param array $aItems
|
659 |
* @return array
|
660 |
+
* @deprecated 9.2.0
|
661 |
*/
|
662 |
public function addAdminMenuBarItems( array $aItems ) {
|
663 |
return $aItems;
|
737 |
/**
|
738 |
* @param array $aSummaryData
|
739 |
* @return array
|
740 |
+
* @deprecated 9.2.0
|
741 |
*/
|
742 |
public function addModuleSummaryData( $aSummaryData ) {
|
|
|
|
|
|
|
743 |
return $aSummaryData;
|
744 |
}
|
745 |
|
746 |
/**
|
747 |
+
* TODO: not the place for this method.
|
748 |
+
* @return array[]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
749 |
*/
|
750 |
+
public function getModulesSummaryData() {
|
751 |
+
return array_map(
|
752 |
+
function ( $mod ) {
|
753 |
+
return $mod->buildSummaryData();
|
754 |
+
},
|
755 |
+
$this->getCon()->modules
|
756 |
+
);
|
757 |
}
|
758 |
|
759 |
/**
|
760 |
* @return array
|
761 |
*/
|
762 |
+
public function buildSummaryData() {
|
763 |
+
$opts = $this->getOptions();
|
764 |
+
$sMenuTitle = $opts->getFeatureProperty( 'menu_title' );
|
765 |
|
766 |
+
$aSections = $opts->getSections();
|
767 |
foreach ( $aSections as $sSlug => $aSection ) {
|
768 |
try {
|
769 |
$aStrings = $this->getStrings()->getSectionStrings( $aSection[ 'slug' ] );
|
772 |
$aSection[ $sKey ] = $sVal;
|
773 |
}
|
774 |
}
|
775 |
+
catch ( \Exception $e ) {
|
776 |
}
|
777 |
}
|
778 |
|
779 |
$aSum = [
|
780 |
+
'slug' => $this->getSlug(),
|
781 |
+
'enabled' => $this->getUIHandler()->isEnabledForUiSummary(),
|
782 |
+
'active' => $this->isThisModulePage() || $this->isPage_InsightsThisModule(),
|
783 |
+
'name' => $this->getMainFeatureName(),
|
784 |
+
'sidebar_name' => $opts->getFeatureProperty( 'sidebar_name' ),
|
785 |
+
'menu_title' => empty( $sMenuTitle ) ? $this->getMainFeatureName() : __( $sMenuTitle, 'wp-simple-firewall' ),
|
786 |
+
'href' => network_admin_url( 'admin.php?page='.$this->getModSlug() ),
|
787 |
+
'sections' => $aSections,
|
788 |
+
'options' => [],
|
789 |
+
'show_mod_opts' => $this->getIfShowModuleOpts(),
|
790 |
];
|
791 |
|
792 |
+
foreach ( $opts->getVisibleOptionsKeys() as $sOptKey ) {
|
793 |
try {
|
794 |
$aOptData = $this->getStrings()->getOptionStrings( $sOptKey );
|
795 |
$aOptData[ 'href' ] = $this->getUrl_DirectLinkToOption( $sOptKey );
|
796 |
$aSum[ 'options' ][ $sOptKey ] = $aOptData;
|
797 |
}
|
798 |
+
catch ( \Exception $e ) {
|
799 |
}
|
800 |
}
|
801 |
|
807 |
}
|
808 |
|
809 |
/**
|
810 |
+
* @param array $aAllNotices
|
811 |
+
* @return array
|
812 |
+
* @deprecated 9.2.0
|
813 |
*/
|
814 |
+
public function addInsightsNoticeData( $aAllNotices ) {
|
815 |
+
return $aAllNotices;
|
816 |
+
}
|
817 |
+
|
818 |
+
/**
|
819 |
+
* @param array $aAllData
|
820 |
+
* @return array
|
821 |
+
* @deprecated 9.2.0
|
822 |
+
*/
|
823 |
+
public function addInsightsConfigData( $aAllData ) {
|
824 |
+
return $aAllData;
|
825 |
}
|
826 |
|
827 |
/**
|
828 |
* @return bool
|
829 |
+
* @deprecated 9.2.0
|
830 |
*/
|
831 |
+
public function isEnabledForUiSummary() {
|
832 |
+
return $this->isModuleEnabled();
|
833 |
}
|
834 |
|
835 |
/**
|
836 |
* @return bool
|
837 |
*/
|
838 |
+
public function getIfShowModuleMenuItem() {
|
839 |
+
return (bool)$this->getOptions()->getFeatureProperty( 'show_module_menu_item' );
|
840 |
}
|
841 |
|
842 |
/**
|
843 |
* @return bool
|
844 |
*/
|
845 |
+
public function getIfShowModuleOpts() {
|
846 |
+
return (bool)$this->getOptions()->getFeatureProperty( 'show_module_options' );
|
847 |
}
|
848 |
|
849 |
/**
|
941 |
|
942 |
/**
|
943 |
* Sets the value for the given option key
|
|
|
944 |
* @param string $sOptionKey
|
945 |
* @param mixed $mValue
|
946 |
* @return $this
|
1080 |
* It doesn't set any values, just populates the array created in buildOptions()
|
1081 |
* with values stored.
|
1082 |
* It has to handle the conversion of stored values to data to be displayed to the user.
|
1083 |
+
* @deprecated 9.2.0
|
1084 |
*/
|
1085 |
public function buildOptions() {
|
1086 |
+
return $this->getUIHandler()->buildOptions();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1087 |
}
|
1088 |
|
1089 |
/**
|
1090 |
* @param array $aOptParams
|
1091 |
* @return array
|
1092 |
+
* @deprecated 9.2.0
|
1093 |
*/
|
1094 |
protected function buildOptionForUi( $aOptParams ) {
|
1095 |
+
return [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1096 |
}
|
1097 |
|
1098 |
/**
|
1119 |
protected function getAllFormOptionsAndTypes() {
|
1120 |
$aOpts = [];
|
1121 |
|
1122 |
+
foreach ( $this->getUIHandler()->buildOptions() as $aOptionsSection ) {
|
1123 |
if ( !empty( $aOptionsSection ) ) {
|
1124 |
foreach ( $aOptionsSection[ 'options' ] as $aOption ) {
|
1125 |
$aOpts[ $aOption[ 'key' ] ] = $aOption[ 'type' ];
|
1332 |
* @return string
|
1333 |
*/
|
1334 |
protected function renderModulePage( $aData = [] ) {
|
1335 |
+
return $this->renderTemplate(
|
1336 |
+
'index.php',
|
1337 |
+
Services::DataManipulation()->mergeArraysRecursive( $this->getUIHandler()->getBaseDisplayData(), $aData )
|
1338 |
+
);
|
|
|
|
|
1339 |
}
|
1340 |
|
1341 |
/**
|
1342 |
* @return array
|
1343 |
+
* @deprecated 9.2.0
|
1344 |
*/
|
1345 |
public function getBaseDisplayData() {
|
1346 |
+
return $this->getUIHandler()->getBaseDisplayData();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1347 |
}
|
1348 |
|
1349 |
/**
|
1350 |
* @return string
|
1351 |
*/
|
1352 |
protected function getContentWizardLanding() {
|
1353 |
+
$aData = $this->getUIHandler()->getBaseDisplayData();
|
1354 |
if ( $this->hasWizard() ) {
|
1355 |
$aData[ 'content' ][ 'wizard_landing' ] = $this->getWizardHandler()->renderWizardLandingSnippet();
|
1356 |
}
|
1377 |
);
|
1378 |
}
|
1379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1380 |
/**
|
1381 |
* @param string $sWizardSlug
|
1382 |
* @return string
|
1405 |
/**
|
1406 |
* @return string
|
1407 |
*/
|
1408 |
+
public function getUrl_WizardLanding() {
|
1409 |
return $this->getUrl_Wizard( 'landing' );
|
1410 |
}
|
1411 |
|
1449 |
/**
|
1450 |
* @return bool
|
1451 |
*/
|
1452 |
+
public function getIsShowMarketing() {
|
1453 |
return apply_filters( $this->prefix( 'show_marketing' ), !$this->isPremium() );
|
1454 |
}
|
1455 |
|
1469 |
return $this->getCon()
|
1470 |
->getRenderer()
|
1471 |
->setTemplate( $sTemplate )
|
1472 |
+
->setRenderVars( $this->getUIHandler()->getBaseDisplayData() )
|
1473 |
->setTemplateEngineTwig()
|
1474 |
->render();
|
1475 |
}
|
1481 |
/**
|
1482 |
* @return bool
|
1483 |
*/
|
1484 |
+
public function canDisplayOptionsForm() {
|
1485 |
return $this->getOptions()->isAccessRestricted() ? $this->getCon()->isPluginAdmin() : true;
|
1486 |
}
|
1487 |
|
1634 |
return $aData;
|
1635 |
}
|
1636 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1637 |
/**
|
1638 |
* @return null|Shield\Modules\Base\ShieldOptions|mixed
|
1639 |
*/
|
1667 |
return $this->oWpCli;
|
1668 |
}
|
1669 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1670 |
/**
|
1671 |
* @return null|Shield\Modules\Base\Strings
|
1672 |
*/
|
1677 |
return $this->oStrings;
|
1678 |
}
|
1679 |
|
1680 |
+
/**
|
1681 |
+
* @return Shield\Modules\Base\UI
|
1682 |
+
*/
|
1683 |
+
public function getUIHandler() {
|
1684 |
+
if ( !isset( $this->oUI ) ) {
|
1685 |
+
$this->oUI = $this->loadClass( 'UI' );
|
1686 |
+
if ( !$this->oUI instanceof Shield\Modules\Base\UI ) {
|
1687 |
+
// TODO: autoloader for base classes
|
1688 |
+
$this->oUI = $this->loadClassFromBase( 'ShieldUI' );
|
1689 |
+
}
|
1690 |
+
$this->oUI->setMod( $this );
|
1691 |
+
}
|
1692 |
+
return $this->oUI;
|
1693 |
+
}
|
1694 |
+
|
1695 |
/**
|
1696 |
* @return Shield\Modules\Base\BaseReporting|mixed|false
|
1697 |
*/
|
1796 |
protected function doExtraSubmitProcessing() {
|
1797 |
$this->preProcessOptions();
|
1798 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1799 |
}
|
src/features/base_wpsf.php
CHANGED
@@ -56,7 +56,7 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
56 |
* @return bool
|
57 |
*/
|
58 |
public function hasSession() {
|
59 |
-
return
|
60 |
}
|
61 |
|
62 |
/**
|
@@ -157,55 +157,6 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
157 |
}
|
158 |
}
|
159 |
|
160 |
-
/**
|
161 |
-
* @return array
|
162 |
-
*/
|
163 |
-
public function getBaseDisplayData() {
|
164 |
-
return Services::DataManipulation()->mergeArraysRecursive(
|
165 |
-
parent::getBaseDisplayData(),
|
166 |
-
[
|
167 |
-
'head' => [
|
168 |
-
'html' => [
|
169 |
-
'lang' => Services::WpGeneral()->getLocale( '-' ),
|
170 |
-
'dir' => is_rtl() ? 'rtl' : 'ltr',
|
171 |
-
],
|
172 |
-
'meta' => [
|
173 |
-
[
|
174 |
-
'type' => 'http-equiv',
|
175 |
-
'type_type' => 'Cache-Control',
|
176 |
-
'content' => 'no-store, no-cache',
|
177 |
-
],
|
178 |
-
[
|
179 |
-
'type' => 'http-equiv',
|
180 |
-
'type_type' => 'Expires',
|
181 |
-
'content' => '0',
|
182 |
-
],
|
183 |
-
],
|
184 |
-
'scripts' => []
|
185 |
-
],
|
186 |
-
'ajax' => [
|
187 |
-
'sec_admin_login' => $this->getSecAdminLoginAjaxData(),
|
188 |
-
],
|
189 |
-
'flags' => [
|
190 |
-
'show_promo' => !$this->isPremium(),
|
191 |
-
'has_session' => $this->hasSession()
|
192 |
-
],
|
193 |
-
'hrefs' => [
|
194 |
-
'aar_forget_key' => $this->isWlEnabled() ?
|
195 |
-
$this->getCon()->getLabels()[ 'AuthorURI' ] : 'https://shsec.io/gc'
|
196 |
-
],
|
197 |
-
'classes' => [
|
198 |
-
'top_container' => implode( ' ', array_filter( [
|
199 |
-
'odp-outercontainer',
|
200 |
-
$this->isPremium() ? 'is-pro' : 'is-not-pro',
|
201 |
-
$this->getModSlug(),
|
202 |
-
Services::Request()->query( 'inav', '' )
|
203 |
-
] ) )
|
204 |
-
],
|
205 |
-
]
|
206 |
-
);
|
207 |
-
}
|
208 |
-
|
209 |
/**
|
210 |
* @return string
|
211 |
*/
|
@@ -216,7 +167,7 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
216 |
->getOptions();
|
217 |
$aData = Services::DataManipulation()
|
218 |
->mergeArraysRecursive(
|
219 |
-
$this->getBaseDisplayData(),
|
220 |
[
|
221 |
'ajax' => [
|
222 |
'restricted_access' => $this->getAjaxActionData( 'restricted_access' ),
|
@@ -329,17 +280,4 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
329 |
}
|
330 |
return array_unique( array_filter( $aCleaned ) );
|
331 |
}
|
332 |
-
|
333 |
-
/**
|
334 |
-
* @return array
|
335 |
-
*/
|
336 |
-
protected function getModDisabledInsight() {
|
337 |
-
return [
|
338 |
-
'name' => __( 'Module Disabled', 'wp-simple-firewall' ),
|
339 |
-
'enabled' => false,
|
340 |
-
'summary' => __( 'All features of this module are completely disabled', 'wp-simple-firewall' ),
|
341 |
-
'weight' => 2,
|
342 |
-
'href' => $this->getUrl_DirectLinkToOption( $this->getEnableModOptKey() ),
|
343 |
-
];
|
344 |
-
}
|
345 |
}
|
56 |
* @return bool
|
57 |
*/
|
58 |
public function hasSession() {
|
59 |
+
return $this->getSession() instanceof Shield\Databases\Session\EntryVO;
|
60 |
}
|
61 |
|
62 |
/**
|
157 |
}
|
158 |
}
|
159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
/**
|
161 |
* @return string
|
162 |
*/
|
167 |
->getOptions();
|
168 |
$aData = Services::DataManipulation()
|
169 |
->mergeArraysRecursive(
|
170 |
+
$this->getUIHandler()->getBaseDisplayData(),
|
171 |
[
|
172 |
'ajax' => [
|
173 |
'restricted_access' => $this->getAjaxActionData( 'restricted_access' ),
|
280 |
}
|
281 |
return array_unique( array_filter( $aCleaned ) );
|
282 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
}
|
src/features/comments_filter.php
CHANGED
@@ -19,25 +19,26 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
|
|
19 |
}
|
20 |
|
21 |
public function ensureCorrectCaptchaConfig() {
|
22 |
-
/** @var CommentsFilter\Options $
|
23 |
-
$
|
24 |
|
25 |
-
$sStyle = $
|
26 |
if ( $this->isPremium() ) {
|
27 |
$oCfg = $this->getCaptchaCfg();
|
28 |
if ( $oCfg->provider == $oCfg::PROV_GOOGLE_RECAP2 ) {
|
29 |
if ( !$oCfg->invisible && $sStyle == 'invisible' ) {
|
30 |
-
$
|
31 |
}
|
32 |
}
|
33 |
}
|
34 |
elseif ( !in_array( $sStyle, [ 'disabled', 'default' ] ) ) {
|
35 |
-
$
|
36 |
}
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
* @return bool
|
|
|
41 |
*/
|
42 |
public function getApprovedMinimum() {
|
43 |
return $this->getOpt( 'trusted_commenter_minimum', 1 );
|
@@ -45,6 +46,7 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
|
|
45 |
|
46 |
/**
|
47 |
* @return string[]
|
|
|
48 |
*/
|
49 |
public function getTrustedRoles() {
|
50 |
$aRoles = [];
|
@@ -81,90 +83,52 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
|
|
81 |
}
|
82 |
|
83 |
protected function preProcessOptions() {
|
84 |
-
/** @var
|
85 |
-
$
|
86 |
|
87 |
// clean roles
|
88 |
-
$
|
89 |
array_unique( array_filter( array_map(
|
90 |
function ( $sRole ) {
|
91 |
return sanitize_key( strtolower( $sRole ) );
|
92 |
},
|
93 |
-
$
|
94 |
) ) )
|
95 |
);
|
96 |
|
97 |
$this->ensureCorrectCaptchaConfig();
|
98 |
}
|
99 |
|
100 |
-
/**
|
101 |
-
* @param array $aAllData
|
102 |
-
* @return array
|
103 |
-
*/
|
104 |
-
public function addInsightsConfigData( $aAllData ) {
|
105 |
-
$aThis = [
|
106 |
-
'strings' => [
|
107 |
-
'title' => __( 'SPAM Blocking', 'wp-simple-firewall' ),
|
108 |
-
'sub' => __( 'Block Bot & Human Comment SPAM', 'wp-simple-firewall' ),
|
109 |
-
],
|
110 |
-
'key_opts' => [],
|
111 |
-
'href_options' => $this->getUrl_AdminPage()
|
112 |
-
];
|
113 |
-
|
114 |
-
if ( !$this->isModOptEnabled() ) {
|
115 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
116 |
-
}
|
117 |
-
else {
|
118 |
-
$aThis[ 'key_opts' ][ 'bot' ] = [
|
119 |
-
'name' => __( 'Bot SPAM', 'wp-simple-firewall' ),
|
120 |
-
'enabled' => $this->isEnabledGaspCheck() || $this->isEnabledCaptcha(),
|
121 |
-
'summary' => ( $this->isEnabledGaspCheck() || $this->isEnabledCaptcha() ) ?
|
122 |
-
__( 'Bot SPAM comments are blocked', 'wp-simple-firewall' )
|
123 |
-
: __( 'There is no protection against Bot SPAM comments', 'wp-simple-firewall' ),
|
124 |
-
'weight' => 2,
|
125 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_bot_comment_spam_protection_filter' ),
|
126 |
-
];
|
127 |
-
$aThis[ 'key_opts' ][ 'human' ] = [
|
128 |
-
'name' => __( 'Human SPAM', 'wp-simple-firewall' ),
|
129 |
-
'enabled' => $this->isEnabledHumanCheck(),
|
130 |
-
'summary' => $this->isEnabledHumanCheck() ?
|
131 |
-
__( 'Comments posted by humans are checked for SPAM', 'wp-simple-firewall' )
|
132 |
-
: __( "Comments posted by humans aren't checked for SPAM", 'wp-simple-firewall' ),
|
133 |
-
'weight' => 1,
|
134 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_human_spam_filter' ),
|
135 |
-
];
|
136 |
-
}
|
137 |
-
|
138 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
139 |
-
return $aAllData;
|
140 |
-
}
|
141 |
-
|
142 |
/**
|
143 |
* @return bool
|
144 |
*/
|
145 |
public function isEnabledCaptcha() {
|
146 |
-
|
|
|
|
|
147 |
&& $this->getCaptchaCfg()->ready;
|
148 |
}
|
149 |
|
150 |
/**
|
151 |
* @return bool
|
|
|
152 |
*/
|
153 |
public function isEnabledGaspCheck() {
|
154 |
-
/** @var CommentsFilter\Options $
|
155 |
-
$
|
156 |
return $this->isModOptEnabled() && $this->isOpt( 'enable_comments_gasp_protection', 'Y' )
|
157 |
-
&& ( $
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
* @return bool
|
|
|
162 |
*/
|
163 |
public function isEnabledHumanCheck() {
|
164 |
-
/** @var CommentsFilter\Options $
|
165 |
-
$
|
166 |
-
return $
|
167 |
-
&& count( $
|
168 |
}
|
169 |
|
170 |
/**
|
19 |
}
|
20 |
|
21 |
public function ensureCorrectCaptchaConfig() {
|
22 |
+
/** @var CommentsFilter\Options $opts */
|
23 |
+
$opts = $this->getOptions();
|
24 |
|
25 |
+
$sStyle = $opts->getOpt( 'google_recaptcha_style_comments' );
|
26 |
if ( $this->isPremium() ) {
|
27 |
$oCfg = $this->getCaptchaCfg();
|
28 |
if ( $oCfg->provider == $oCfg::PROV_GOOGLE_RECAP2 ) {
|
29 |
if ( !$oCfg->invisible && $sStyle == 'invisible' ) {
|
30 |
+
$opts->setOpt( 'google_recaptcha_style_comments', 'default' );
|
31 |
}
|
32 |
}
|
33 |
}
|
34 |
elseif ( !in_array( $sStyle, [ 'disabled', 'default' ] ) ) {
|
35 |
+
$opts->setOpt( 'google_recaptcha_style_comments', 'default' );
|
36 |
}
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
* @return bool
|
41 |
+
* @deprecated 9.2.0
|
42 |
*/
|
43 |
public function getApprovedMinimum() {
|
44 |
return $this->getOpt( 'trusted_commenter_minimum', 1 );
|
46 |
|
47 |
/**
|
48 |
* @return string[]
|
49 |
+
* @deprecated 9.2.0
|
50 |
*/
|
51 |
public function getTrustedRoles() {
|
52 |
$aRoles = [];
|
83 |
}
|
84 |
|
85 |
protected function preProcessOptions() {
|
86 |
+
/** @var CommentsFilter\Options $opts */
|
87 |
+
$opts = $this->getOptions();
|
88 |
|
89 |
// clean roles
|
90 |
+
$opts->setOpt( 'trusted_user_roles',
|
91 |
array_unique( array_filter( array_map(
|
92 |
function ( $sRole ) {
|
93 |
return sanitize_key( strtolower( $sRole ) );
|
94 |
},
|
95 |
+
$opts->getTrustedRoles()
|
96 |
) ) )
|
97 |
);
|
98 |
|
99 |
$this->ensureCorrectCaptchaConfig();
|
100 |
}
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
/**
|
103 |
* @return bool
|
104 |
*/
|
105 |
public function isEnabledCaptcha() {
|
106 |
+
/** @var CommentsFilter\Options $opts */
|
107 |
+
$opts = $this->getOptions();
|
108 |
+
return $this->isModOptEnabled() && !$opts->isEnabledCaptcha()
|
109 |
&& $this->getCaptchaCfg()->ready;
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
* @return bool
|
114 |
+
* @deprecated 9.2
|
115 |
*/
|
116 |
public function isEnabledGaspCheck() {
|
117 |
+
/** @var CommentsFilter\Options $opts */
|
118 |
+
$opts = $this->getOptions();
|
119 |
return $this->isModOptEnabled() && $this->isOpt( 'enable_comments_gasp_protection', 'Y' )
|
120 |
+
&& ( $opts->getTokenExpireInterval() > $opts->getTokenCooldown() );
|
121 |
}
|
122 |
|
123 |
/**
|
124 |
* @return bool
|
125 |
+
* @deprecated 9.2
|
126 |
*/
|
127 |
public function isEnabledHumanCheck() {
|
128 |
+
/** @var CommentsFilter\Options $opts */
|
129 |
+
$opts = $this->getOptions();
|
130 |
+
return $opts->isOpt( 'enable_comments_human_spam_filter', 'Y' )
|
131 |
+
&& count( $opts->getHumanSpamFilterItems() ) > 0;
|
132 |
}
|
133 |
|
134 |
/**
|
src/features/firewall.php
CHANGED
@@ -56,54 +56,6 @@ class ICWP_WPSF_FeatureHandler_Firewall extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
56 |
return $sText;
|
57 |
}
|
58 |
|
59 |
-
/**
|
60 |
-
* @param array $aAllData
|
61 |
-
* @return array
|
62 |
-
*/
|
63 |
-
public function addInsightsConfigData( $aAllData ) {
|
64 |
-
/** @var Firewall\Options $oOpts */
|
65 |
-
$oOpts = $this->getOptions();
|
66 |
-
|
67 |
-
$aThis = [
|
68 |
-
'strings' => [
|
69 |
-
'title' => __( 'Firewall', 'wp-simple-firewall' ),
|
70 |
-
'sub' => __( 'Block Malicious Requests', 'wp-simple-firewall' ),
|
71 |
-
],
|
72 |
-
'key_opts' => [],
|
73 |
-
'href_options' => $this->getUrl_AdminPage()
|
74 |
-
];
|
75 |
-
|
76 |
-
if ( !$this->isModOptEnabled() ) {
|
77 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
78 |
-
}
|
79 |
-
else {
|
80 |
-
$aThis[ 'key_opts' ][ 'mod' ] = [
|
81 |
-
'name' => __( 'Firewall', 'wp-simple-firewall' ),
|
82 |
-
'enabled' => $this->isModOptEnabled(),
|
83 |
-
'summary' => $this->isModOptEnabled() ?
|
84 |
-
__( 'Your site is protected against malicious requests', 'wp-simple-firewall' )
|
85 |
-
: __( 'Your site is not protected against malicious requests', 'wp-simple-firewall' ),
|
86 |
-
'weight' => 2,
|
87 |
-
'href' => $this->getUrl_DirectLinkToOption( $this->getEnableModOptKey() ),
|
88 |
-
];
|
89 |
-
|
90 |
-
//ignoring admin isn't a good idea
|
91 |
-
$bAdminIncluded = !$oOpts->isIgnoreAdmin();
|
92 |
-
$aThis[ 'key_opts' ][ 'admin' ] = [
|
93 |
-
'name' => __( 'Ignore Admins', 'wp-simple-firewall' ),
|
94 |
-
'enabled' => $bAdminIncluded,
|
95 |
-
'summary' => $bAdminIncluded ?
|
96 |
-
__( "Firewall rules are also applied to admins", 'wp-simple-firewall' )
|
97 |
-
: __( "Firewall rules aren't applied to admins", 'wp-simple-firewall' ),
|
98 |
-
'weight' => 1,
|
99 |
-
'href' => $this->getUrl_DirectLinkToOption( 'whitelist_admins' ),
|
100 |
-
];
|
101 |
-
}
|
102 |
-
|
103 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
104 |
-
return $aAllData;
|
105 |
-
}
|
106 |
-
|
107 |
/**
|
108 |
* @return string
|
109 |
*/
|
56 |
return $sText;
|
57 |
}
|
58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
/**
|
60 |
* @return string
|
61 |
*/
|
src/features/hack_protect.php
CHANGED
@@ -56,34 +56,34 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
56 |
* @return HackGuard\Scan\Controller\Base[]
|
57 |
*/
|
58 |
public function getAllScanCons() {
|
59 |
-
/** @var HackGuard\Options $
|
60 |
-
$
|
61 |
-
foreach ( $
|
62 |
$this->getScanCon( $scanSlug );
|
63 |
}
|
64 |
return $this->aScanCons;
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
-
* @param string $
|
69 |
* @return HackGuard\Scan\Controller\Base|mixed
|
70 |
*/
|
71 |
-
public function getScanCon( $
|
72 |
if ( !is_array( $this->aScanCons ) ) {
|
73 |
$this->aScanCons = [];
|
74 |
}
|
75 |
-
if ( !isset( $this->aScanCons[ $
|
76 |
-
$
|
77 |
-
if ( @class_exists( $
|
78 |
/** @var HackGuard\Scan\Controller\Base $oObj */
|
79 |
-
$oObj = new $
|
80 |
-
$this->aScanCons[ $
|
81 |
}
|
82 |
else {
|
83 |
-
$this->aScanCons[ $
|
84 |
}
|
85 |
}
|
86 |
-
return $this->aScanCons[ $
|
87 |
}
|
88 |
|
89 |
/**
|
@@ -106,28 +106,34 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
106 |
}
|
107 |
|
108 |
protected function preProcessOptions() {
|
109 |
-
/** @var HackGuard\Options $
|
110 |
-
$
|
111 |
|
112 |
$this->cleanFileExclusions();
|
113 |
|
114 |
-
if ( $
|
115 |
/** @var \ICWP_WPSF_Processor_HackProtect $oPro */
|
116 |
$oPro = $this->getProcessor();
|
117 |
$oPro->getSubProScanner()->deleteCron();
|
118 |
}
|
119 |
|
120 |
-
if ( count( $
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
$
|
125 |
$this->getFileLocker()->purge();
|
126 |
}
|
127 |
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
132 |
}
|
133 |
}
|
@@ -171,9 +177,9 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
171 |
* @return $this
|
172 |
*/
|
173 |
protected function setCustomCronSchedules() {
|
174 |
-
/** @var HackGuard\Options $
|
175 |
-
$
|
176 |
-
$nFreq = $
|
177 |
Services::WpCron()
|
178 |
->addNewSchedule(
|
179 |
$this->prefix( sprintf( 'per-day-%s', $nFreq ) ),
|
@@ -248,10 +254,10 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
248 |
public function insertCustomJsVars_Admin() {
|
249 |
parent::insertCustomJsVars_Admin();
|
250 |
|
251 |
-
/** @var HackGuard\Options $
|
252 |
-
$
|
253 |
if ( Services::WpPost()->isCurrentPage( 'plugins.php' )
|
254 |
-
&& $
|
255 |
wp_localize_script(
|
256 |
$this->prefix( 'global-plugin' ),
|
257 |
'icwp_wpsf_vars_hp',
|
@@ -273,35 +279,6 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
273 |
}
|
274 |
}
|
275 |
|
276 |
-
/**
|
277 |
-
* @param string $sSection
|
278 |
-
* @return array
|
279 |
-
*/
|
280 |
-
protected function getSectionWarnings( $sSection ) {
|
281 |
-
$aWarnings = [];
|
282 |
-
|
283 |
-
switch ( $sSection ) {
|
284 |
-
|
285 |
-
case 'section_realtime':
|
286 |
-
$bCanHandshake = $this->getCon()
|
287 |
-
->getModule_Plugin()
|
288 |
-
->getShieldNetApiController()
|
289 |
-
->canHandshake();
|
290 |
-
if ( !$bCanHandshake ) {
|
291 |
-
$aWarnings[] = sprintf( __( 'Not available as your site cannot handshake with ShieldNET API.', 'wp-simple-firewall' ), 'OpenSSL' );
|
292 |
-
}
|
293 |
-
// if ( !Services::Encrypt()->isSupportedOpenSslDataEncryption() ) {
|
294 |
-
// $aWarnings[] = sprintf( __( 'Not available because the %s extension is not available.', 'wp-simple-firewall' ), 'OpenSSL' );
|
295 |
-
// }
|
296 |
-
// if ( !Services::WpFs()->isFilesystemAccessDirect() ) {
|
297 |
-
// $aWarnings[] = sprintf( __( "Not available because PHP/WordPress doesn't have direct filesystem access.", 'wp-simple-firewall' ), 'OpenSSL' );
|
298 |
-
// }
|
299 |
-
break;
|
300 |
-
}
|
301 |
-
|
302 |
-
return $aWarnings;
|
303 |
-
}
|
304 |
-
|
305 |
/**
|
306 |
* @return string|false
|
307 |
*/
|
@@ -325,298 +302,6 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
325 |
return Services::WpFs()->mkdir( $sDir ) ? $sDir : false;
|
326 |
}
|
327 |
|
328 |
-
/**
|
329 |
-
* @param array $aAllNotices
|
330 |
-
* @return array
|
331 |
-
*/
|
332 |
-
public function addInsightsNoticeData( $aAllNotices ) {
|
333 |
-
/** @var HackGuard\Strings $oStrings */
|
334 |
-
$oStrings = $this->getStrings();
|
335 |
-
$aScanNames = $oStrings->getScanNames();
|
336 |
-
|
337 |
-
$aNotices = [
|
338 |
-
'title' => __( 'Scans', 'wp-simple-firewall' ),
|
339 |
-
'messages' => []
|
340 |
-
];
|
341 |
-
|
342 |
-
$sScansUrl = $this->getCon()->getModule_Insights()->getUrl_SubInsightsPage( 'scans' );
|
343 |
-
|
344 |
-
{// Core files
|
345 |
-
if ( !$this->isScanEnabled( 'wcf' ) ) {
|
346 |
-
$aNotices[ 'messages' ][ 'wcf' ] = [
|
347 |
-
'title' => $aScanNames[ 'wcf' ],
|
348 |
-
'message' => __( 'Core File scanner is not enabled.', 'wp-simple-firewall' ),
|
349 |
-
'href' => $this->getUrl_DirectLinkToOption( 'enable_core_file_integrity_scan' ),
|
350 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
351 |
-
'rec' => __( 'Automatic WordPress Core File scanner should be turned-on.', 'wp-simple-firewall' )
|
352 |
-
];
|
353 |
-
}
|
354 |
-
elseif ( $this->getScanCon( 'wcf' )->getScanHasProblem() ) {
|
355 |
-
$aNotices[ 'messages' ][ 'wcf' ] = [
|
356 |
-
'title' => $aScanNames[ 'wcf' ],
|
357 |
-
'message' => __( 'Modified WordPress core files found.', 'wp-simple-firewall' ),
|
358 |
-
'href' => $sScansUrl,
|
359 |
-
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
360 |
-
'rec' => __( 'Scan WP core files and repair any files that are flagged as modified.', 'wp-simple-firewall' )
|
361 |
-
];
|
362 |
-
}
|
363 |
-
}
|
364 |
-
|
365 |
-
{// Unrecognised
|
366 |
-
if ( !$this->isScanEnabled( 'ufc' ) ) {
|
367 |
-
$aNotices[ 'messages' ][ 'ufc' ] = [
|
368 |
-
'title' => $aScanNames[ 'ufc' ],
|
369 |
-
'message' => __( 'Unrecognised File scanner is not enabled.', 'wp-simple-firewall' ),
|
370 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
371 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
372 |
-
'rec' => __( 'Automatic scanning for non-WordPress core files is recommended.', 'wp-simple-firewall' )
|
373 |
-
];
|
374 |
-
}
|
375 |
-
elseif ( $this->getScanCon( 'ufc' )->getScanHasProblem() ) {
|
376 |
-
$aNotices[ 'messages' ][ 'ufc' ] = [
|
377 |
-
'title' => $aScanNames[ 'ufc' ],
|
378 |
-
'message' => __( 'Unrecognised files found in WordPress Core directory.', 'wp-simple-firewall' ),
|
379 |
-
'href' => $sScansUrl,
|
380 |
-
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
381 |
-
'rec' => __( 'Scan and remove any files that are not meant to be in the WP core directories.', 'wp-simple-firewall' )
|
382 |
-
];
|
383 |
-
}
|
384 |
-
}
|
385 |
-
|
386 |
-
{// Plugin/Theme Guard
|
387 |
-
$oPTG = $this->getScanCon( 'ptg' );
|
388 |
-
if ( !$oPTG->isEnabled() ) {
|
389 |
-
$aNotices[ 'messages' ][ 'ptg' ] = [
|
390 |
-
'title' => $aScanNames[ 'ptg' ],
|
391 |
-
'message' => __( 'Automatic Plugin/Themes Guard is not enabled.', 'wp-simple-firewall' ),
|
392 |
-
'href' => $this->getUrl_DirectLinkToOption( 'ptg_enable' ),
|
393 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
394 |
-
'rec' => __( 'Automatic detection of plugin/theme modifications is recommended.', 'wp-simple-firewall' )
|
395 |
-
];
|
396 |
-
}
|
397 |
-
elseif ( $oPTG->getScanHasProblem() ) {
|
398 |
-
$aNotices[ 'messages' ][ 'ptg' ] = [
|
399 |
-
'title' => $aScanNames[ 'ptg' ],
|
400 |
-
'message' => __( 'A plugin/theme was found to have been modified.', 'wp-simple-firewall' ),
|
401 |
-
'href' => $sScansUrl,
|
402 |
-
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
403 |
-
'rec' => __( 'Reviewing modifications to your plugins/themes is recommended.', 'wp-simple-firewall' )
|
404 |
-
];
|
405 |
-
}
|
406 |
-
}
|
407 |
-
|
408 |
-
{// Vulnerability Scanner
|
409 |
-
if ( !$this->isScanEnabled( 'wpv' ) ) {
|
410 |
-
$aNotices[ 'messages' ][ 'wpv' ] = [
|
411 |
-
'title' => $aScanNames[ 'wpv' ],
|
412 |
-
'message' => __( 'Vulnerability Scanner is not enabled.', 'wp-simple-firewall' ),
|
413 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_wpv' ),
|
414 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
415 |
-
'rec' => __( 'Automatic detection of vulnerabilities is recommended.', 'wp-simple-firewall' )
|
416 |
-
];
|
417 |
-
}
|
418 |
-
elseif ( $this->getScanCon( 'wpv' )->getScanHasProblem() ) {
|
419 |
-
$aNotices[ 'messages' ][ 'wpv' ] = [
|
420 |
-
'title' => $aScanNames[ 'wpv' ],
|
421 |
-
'message' => __( 'At least 1 item has known vulnerabilities.', 'wp-simple-firewall' ),
|
422 |
-
'href' => $sScansUrl,
|
423 |
-
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
424 |
-
'rec' => __( 'Items with known vulnerabilities should be updated, removed, or replaced.', 'wp-simple-firewall' )
|
425 |
-
];
|
426 |
-
}
|
427 |
-
}
|
428 |
-
|
429 |
-
{// Abandoned Plugins
|
430 |
-
if ( !$this->isScanEnabled( 'apc' ) ) {
|
431 |
-
$aNotices[ 'messages' ][ 'apc' ] = [
|
432 |
-
'title' => $aScanNames[ 'apc' ],
|
433 |
-
'message' => __( 'Abandoned Plugins Scanner is not enabled.', 'wp-simple-firewall' ),
|
434 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_apc' ),
|
435 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
436 |
-
'rec' => __( 'Automatic detection of abandoned plugins is recommended.', 'wp-simple-firewall' )
|
437 |
-
];
|
438 |
-
}
|
439 |
-
elseif ( $this->getScanCon( 'apc' )->getScanHasProblem() ) {
|
440 |
-
$aNotices[ 'messages' ][ 'apc' ] = [
|
441 |
-
'title' => $aScanNames[ 'apc' ],
|
442 |
-
'message' => __( 'At least 1 plugin on your site is abandoned.', 'wp-simple-firewall' ),
|
443 |
-
'href' => $sScansUrl,
|
444 |
-
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
445 |
-
'rec' => __( 'Plugins that have been abandoned represent a potential risk to your site.', 'wp-simple-firewall' )
|
446 |
-
];
|
447 |
-
}
|
448 |
-
}
|
449 |
-
|
450 |
-
{// Malware
|
451 |
-
if ( !$this->isScanEnabled( 'mal' ) ) {
|
452 |
-
$aNotices[ 'messages' ][ 'mal' ] = [
|
453 |
-
'title' => $aScanNames[ 'mal' ],
|
454 |
-
'message' => sprintf( __( '%s Scanner is not enabled.' ), $aScanNames[ 'mal' ] ),
|
455 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_mal' ),
|
456 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
457 |
-
'rec' => __( 'Automatic detection of Malware is recommended.', 'wp-simple-firewall' )
|
458 |
-
];
|
459 |
-
}
|
460 |
-
elseif ( $this->getScanCon( 'mal' )->getScanHasProblem() ) {
|
461 |
-
$aNotices[ 'messages' ][ 'mal' ] = [
|
462 |
-
'title' => $aScanNames[ 'mal' ],
|
463 |
-
'message' => __( 'At least 1 file with potential Malware has been discovered.', 'wp-simple-firewall' ),
|
464 |
-
'href' => $sScansUrl,
|
465 |
-
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
466 |
-
'rec' => __( 'Files identified as potential malware should be examined as soon as possible.', 'wp-simple-firewall' )
|
467 |
-
];
|
468 |
-
}
|
469 |
-
}
|
470 |
-
|
471 |
-
$aNotices[ 'count' ] = count( $aNotices[ 'messages' ] );
|
472 |
-
|
473 |
-
$aAllNotices[ 'scans' ] = $aNotices;
|
474 |
-
return $aAllNotices;
|
475 |
-
}
|
476 |
-
|
477 |
-
/**
|
478 |
-
* @param array $aAllData
|
479 |
-
* @return array
|
480 |
-
*/
|
481 |
-
public function addInsightsConfigData( $aAllData ) {
|
482 |
-
/** @var HackGuard\Strings $oStrings */
|
483 |
-
$oStrings = $this->getStrings();
|
484 |
-
/** @var HackGuard\Options $oOpts */
|
485 |
-
$oOpts = $this->getOptions();
|
486 |
-
$aScanNames = $oStrings->getScanNames();
|
487 |
-
|
488 |
-
$aThis = [
|
489 |
-
'strings' => [
|
490 |
-
'title' => __( 'Hack Guard', 'wp-simple-firewall' ),
|
491 |
-
'sub' => __( 'Threats/Intrusions Detection & Repair', 'wp-simple-firewall' ),
|
492 |
-
],
|
493 |
-
'key_opts' => [],
|
494 |
-
'href_options' => $this->getUrl_AdminPage()
|
495 |
-
];
|
496 |
-
|
497 |
-
if ( !$this->isModOptEnabled() ) {
|
498 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
499 |
-
}
|
500 |
-
else {
|
501 |
-
$bGoodFrequency = $oOpts->getScanFrequency() > 1;
|
502 |
-
$aThis[ 'key_opts' ][ 'frequency' ] = [
|
503 |
-
'name' => __( 'Scan Frequency', 'wp-simple-firewall' ),
|
504 |
-
'enabled' => $bGoodFrequency,
|
505 |
-
'summary' => $bGoodFrequency ?
|
506 |
-
__( 'Automatic scanners run more than once per day', 'wp-simple-firewall' )
|
507 |
-
: __( "Automatic scanners only run once per day", 'wp-simple-firewall' ),
|
508 |
-
'weight' => 1,
|
509 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_options' ),
|
510 |
-
];
|
511 |
-
|
512 |
-
$bCore = $this->isScanEnabled( 'wcf' );
|
513 |
-
$aThis[ 'key_opts' ][ 'wcf' ] = [
|
514 |
-
'name' => __( 'WP Core File Scan', 'wp-simple-firewall' ),
|
515 |
-
'enabled' => $bCore,
|
516 |
-
'summary' => $bCore ?
|
517 |
-
__( 'Core files scanned regularly for hacks', 'wp-simple-firewall' )
|
518 |
-
: __( "Core files are never scanned for hacks!", 'wp-simple-firewall' ),
|
519 |
-
'weight' => 2,
|
520 |
-
'href' => $this->getUrl_DirectLinkToOption( 'enable_core_file_integrity_scan' ),
|
521 |
-
];
|
522 |
-
if ( $bCore && !$oOpts->isRepairFileWP() ) {
|
523 |
-
$aThis[ 'key_opts' ][ 'wcf_repair' ] = [
|
524 |
-
'name' => __( 'WP Core File Repair', 'wp-simple-firewall' ),
|
525 |
-
'enabled' => $oOpts->isRepairFileWP(),
|
526 |
-
'summary' => $oOpts->isRepairFileWP() ?
|
527 |
-
__( 'Core files are automatically repaired', 'wp-simple-firewall' )
|
528 |
-
: __( "Core files aren't automatically repaired!", 'wp-simple-firewall' ),
|
529 |
-
'weight' => 1,
|
530 |
-
'href' => $this->getUrl_DirectLinkToOption( 'file_repair_areas' ),
|
531 |
-
];
|
532 |
-
}
|
533 |
-
|
534 |
-
$bUcf = $this->isScanEnabled( 'ufc' );
|
535 |
-
$aThis[ 'key_opts' ][ 'ufc' ] = [
|
536 |
-
'name' => __( 'Unrecognised Files', 'wp-simple-firewall' ),
|
537 |
-
'enabled' => $bUcf,
|
538 |
-
'summary' => $bUcf ?
|
539 |
-
__( 'Core directories scanned regularly for unrecognised files', 'wp-simple-firewall' )
|
540 |
-
: __( "WP Core is never scanned for unrecognised files!", 'wp-simple-firewall' ),
|
541 |
-
'weight' => 2,
|
542 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
543 |
-
];
|
544 |
-
if ( $bUcf && !$oOpts->isUfsDeleteFiles() ) {
|
545 |
-
$aThis[ 'key_opts' ][ 'ufc_repair' ] = [
|
546 |
-
'name' => __( 'Unrecognised Files Removal', 'wp-simple-firewall' ),
|
547 |
-
'enabled' => $oOpts->isUfsDeleteFiles(),
|
548 |
-
'summary' => $oOpts->isUfsDeleteFiles() ?
|
549 |
-
__( 'Unrecognised files are automatically removed', 'wp-simple-firewall' )
|
550 |
-
: __( "Unrecognised files aren't automatically removed!", 'wp-simple-firewall' ),
|
551 |
-
'weight' => 1,
|
552 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
553 |
-
];
|
554 |
-
}
|
555 |
-
|
556 |
-
$bWpv = $this->isScanEnabled( 'wpv' );
|
557 |
-
$aThis[ 'key_opts' ][ 'wpv' ] = [
|
558 |
-
'name' => __( 'Vulnerability Scan', 'wp-simple-firewall' ),
|
559 |
-
'enabled' => $bWpv,
|
560 |
-
'summary' => $bWpv ?
|
561 |
-
__( 'Regularly scanning for known vulnerabilities', 'wp-simple-firewall' )
|
562 |
-
: __( "Plugins/Themes never scanned for vulnerabilities!", 'wp-simple-firewall' ),
|
563 |
-
'weight' => 2,
|
564 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_wpv' ),
|
565 |
-
];
|
566 |
-
$bWpvAutoUpdates = $oOpts->isWpvulnAutoupdatesEnabled();
|
567 |
-
if ( $bWpv && !$bWpvAutoUpdates ) {
|
568 |
-
$aThis[ 'key_opts' ][ 'wpv_repair' ] = [
|
569 |
-
'name' => __( 'Auto Update', 'wp-simple-firewall' ),
|
570 |
-
'enabled' => $bWpvAutoUpdates,
|
571 |
-
'summary' => $bWpvAutoUpdates ?
|
572 |
-
__( 'Vulnerable items are automatically updated', 'wp-simple-firewall' )
|
573 |
-
: __( "Vulnerable items aren't automatically updated!", 'wp-simple-firewall' ),
|
574 |
-
'weight' => 1,
|
575 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_wpv' ),
|
576 |
-
];
|
577 |
-
}
|
578 |
-
|
579 |
-
$bPtg = $this->isScanEnabled( 'ptg' );
|
580 |
-
$aThis[ 'key_opts' ][ 'ptg' ] = [
|
581 |
-
'title' => $aScanNames[ 'ptg' ],
|
582 |
-
'name' => __( 'Plugin/Theme Guard', 'wp-simple-firewall' ),
|
583 |
-
'enabled' => $bPtg,
|
584 |
-
'summary' => $bPtg ?
|
585 |
-
__( 'Plugins and Themes are guarded against tampering', 'wp-simple-firewall' )
|
586 |
-
: __( "Plugins and Themes are never scanned for tampering!", 'wp-simple-firewall' ),
|
587 |
-
'weight' => 2,
|
588 |
-
'href' => $this->getUrl_DirectLinkToOption( 'ptg_enable' ),
|
589 |
-
];
|
590 |
-
|
591 |
-
$bMal = $this->isScanEnabled( 'mal' );
|
592 |
-
$aThis[ 'key_opts' ][ 'mal' ] = [
|
593 |
-
'title' => $aScanNames[ 'mal' ],
|
594 |
-
'name' => $aScanNames[ 'mal' ],
|
595 |
-
'enabled' => $bMal,
|
596 |
-
'summary' => $bMal ?
|
597 |
-
sprintf( __( '%s Scanner is enabled.' ), $aScanNames[ 'mal' ] )
|
598 |
-
: sprintf( __( '%s Scanner is not enabled.' ), $aScanNames[ 'mal' ] ),
|
599 |
-
'weight' => 2,
|
600 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_mal' ),
|
601 |
-
];
|
602 |
-
|
603 |
-
$bApc = $this->isScanEnabled( 'apc' );
|
604 |
-
$aThis[ 'key_opts' ][ 'apc' ] = [
|
605 |
-
'title' => $aScanNames[ 'apc' ],
|
606 |
-
'name' => $aScanNames[ 'apc' ],
|
607 |
-
'enabled' => $bApc,
|
608 |
-
'summary' => $bApc ?
|
609 |
-
sprintf( __( '%s Scanner is enabled.' ), $aScanNames[ 'apc' ] )
|
610 |
-
: sprintf( __( '%s Scanner is not enabled.' ), $aScanNames[ 'apc' ] ),
|
611 |
-
'weight' => 2,
|
612 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_scan_apc' ),
|
613 |
-
];
|
614 |
-
}
|
615 |
-
|
616 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
617 |
-
return $aAllData;
|
618 |
-
}
|
619 |
-
|
620 |
/**
|
621 |
* @return Shield\Databases\FileLocker\Handler
|
622 |
*/
|
@@ -657,8 +342,8 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
657 |
foreach ( $oOpts->getScanSlugs() as $sSlug ) {
|
658 |
$this->getScanCon( $sSlug )->purge();
|
659 |
}
|
660 |
-
$this->getDbHandler_ScanQueue()->
|
661 |
-
$this->getDbHandler_ScanResults()->
|
662 |
// 2. Clean out the file locker
|
663 |
$this->getFileLocker()->purge();
|
664 |
}
|
56 |
* @return HackGuard\Scan\Controller\Base[]
|
57 |
*/
|
58 |
public function getAllScanCons() {
|
59 |
+
/** @var HackGuard\Options $opts */
|
60 |
+
$opts = $this->getOptions();
|
61 |
+
foreach ( $opts->getScanSlugs() as $scanSlug ) {
|
62 |
$this->getScanCon( $scanSlug );
|
63 |
}
|
64 |
return $this->aScanCons;
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
+
* @param string $slug
|
69 |
* @return HackGuard\Scan\Controller\Base|mixed
|
70 |
*/
|
71 |
+
public function getScanCon( $slug ) {
|
72 |
if ( !is_array( $this->aScanCons ) ) {
|
73 |
$this->aScanCons = [];
|
74 |
}
|
75 |
+
if ( !isset( $this->aScanCons[ $slug ] ) ) {
|
76 |
+
$class = '\FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller\\'.ucwords( $slug );
|
77 |
+
if ( @class_exists( $class ) ) {
|
78 |
/** @var HackGuard\Scan\Controller\Base $oObj */
|
79 |
+
$oObj = new $class();
|
80 |
+
$this->aScanCons[ $slug ] = $oObj->setMod( $this );
|
81 |
}
|
82 |
else {
|
83 |
+
$this->aScanCons[ $slug ] = false;
|
84 |
}
|
85 |
}
|
86 |
+
return $this->aScanCons[ $slug ];
|
87 |
}
|
88 |
|
89 |
/**
|
106 |
}
|
107 |
|
108 |
protected function preProcessOptions() {
|
109 |
+
/** @var HackGuard\Options $opts */
|
110 |
+
$opts = $this->getOptions();
|
111 |
|
112 |
$this->cleanFileExclusions();
|
113 |
|
114 |
+
if ( $opts->isOptChanged( 'scan_frequency' ) ) {
|
115 |
/** @var \ICWP_WPSF_Processor_HackProtect $oPro */
|
116 |
$oPro = $this->getProcessor();
|
117 |
$oPro->getSubProScanner()->deleteCron();
|
118 |
}
|
119 |
|
120 |
+
if ( count( $opts->getFilesToLock() ) === 0 || !$this->getCon()
|
121 |
+
->getModule_Plugin()
|
122 |
+
->getShieldNetApiController()
|
123 |
+
->canHandshake() ) {
|
124 |
+
$opts->setOpt( 'file_locker', [] );
|
125 |
$this->getFileLocker()->purge();
|
126 |
}
|
127 |
|
128 |
+
$lockFiles = $opts->getFilesToLock();
|
129 |
+
if ( in_array( 'root_webconfig', $lockFiles ) && !Services::Data()->isWindows() ) {
|
130 |
+
unset( $lockFiles[ array_search( 'root_webconfig', $lockFiles ) ] );
|
131 |
+
$opts->setOpt( 'file_locker', $lockFiles );
|
132 |
+
}
|
133 |
+
|
134 |
+
foreach ( $this->getAllScanCons() as $con ) {
|
135 |
+
if ( !$con->isEnabled() ) {
|
136 |
+
$con->purge();
|
137 |
}
|
138 |
}
|
139 |
}
|
177 |
* @return $this
|
178 |
*/
|
179 |
protected function setCustomCronSchedules() {
|
180 |
+
/** @var HackGuard\Options $opts */
|
181 |
+
$opts = $this->getOptions();
|
182 |
+
$nFreq = $opts->getScanFrequency();
|
183 |
Services::WpCron()
|
184 |
->addNewSchedule(
|
185 |
$this->prefix( sprintf( 'per-day-%s', $nFreq ) ),
|
254 |
public function insertCustomJsVars_Admin() {
|
255 |
parent::insertCustomJsVars_Admin();
|
256 |
|
257 |
+
/** @var HackGuard\Options $opts */
|
258 |
+
$opts = $this->getOptions();
|
259 |
if ( Services::WpPost()->isCurrentPage( 'plugins.php' )
|
260 |
+
&& $opts->isPtgReinstallLinks() && $this->getScanCon( 'ptg' )->isReady() ) {
|
261 |
wp_localize_script(
|
262 |
$this->prefix( 'global-plugin' ),
|
263 |
'icwp_wpsf_vars_hp',
|
279 |
}
|
280 |
}
|
281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
/**
|
283 |
* @return string|false
|
284 |
*/
|
302 |
return Services::WpFs()->mkdir( $sDir ) ? $sDir : false;
|
303 |
}
|
304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
/**
|
306 |
* @return Shield\Databases\FileLocker\Handler
|
307 |
*/
|
342 |
foreach ( $oOpts->getScanSlugs() as $sSlug ) {
|
343 |
$this->getScanCon( $sSlug )->purge();
|
344 |
}
|
345 |
+
$this->getDbHandler_ScanQueue()->tableDelete();
|
346 |
+
$this->getDbHandler_ScanResults()->tableDelete();
|
347 |
// 2. Clean out the file locker
|
348 |
$this->getFileLocker()->purge();
|
349 |
}
|
src/features/headers.php
CHANGED
@@ -86,54 +86,6 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
86 |
$oOpts->setOpt( 'xcsp_hosts', array_unique( $aValidDomains ) );
|
87 |
}
|
88 |
|
89 |
-
/**
|
90 |
-
* @param array $aAllData
|
91 |
-
* @return array
|
92 |
-
*/
|
93 |
-
public function addInsightsConfigData( $aAllData ) {
|
94 |
-
/** @var Headers\Options $oOpts */
|
95 |
-
$oOpts = $this->getOptions();
|
96 |
-
|
97 |
-
$aThis = [
|
98 |
-
'strings' => [
|
99 |
-
'title' => __( 'HTTP Security Headers', 'wp-simple-firewall' ),
|
100 |
-
'sub' => __( 'Protect Visitors With Powerful HTTP Headers', 'wp-simple-firewall' ),
|
101 |
-
],
|
102 |
-
'key_opts' => [],
|
103 |
-
'href_options' => $this->getUrl_AdminPage()
|
104 |
-
];
|
105 |
-
|
106 |
-
if ( !$this->isModOptEnabled() ) {
|
107 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
108 |
-
}
|
109 |
-
else {
|
110 |
-
$bAllEnabled = $oOpts->isEnabledXFrame() && $oOpts->isEnabledXssProtection()
|
111 |
-
&& $oOpts->isEnabledContentTypeHeader() && $oOpts->isReferrerPolicyEnabled();
|
112 |
-
$aThis[ 'key_opts' ][ 'all' ] = [
|
113 |
-
'name' => __( 'HTTP Headers', 'wp-simple-firewall' ),
|
114 |
-
'enabled' => $bAllEnabled,
|
115 |
-
'summary' => $bAllEnabled ?
|
116 |
-
__( 'All important security Headers have been set', 'wp-simple-firewall' )
|
117 |
-
: __( "At least one of the HTTP Headers hasn't been set", 'wp-simple-firewall' ),
|
118 |
-
'weight' => 2,
|
119 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_security_headers' ),
|
120 |
-
];
|
121 |
-
$bCsp = $oOpts->isEnabledContentSecurityPolicy();
|
122 |
-
$aThis[ 'key_opts' ][ 'csp' ] = [
|
123 |
-
'name' => __( 'Content Security Policies', 'wp-simple-firewall' ),
|
124 |
-
'enabled' => $bCsp,
|
125 |
-
'summary' => $bCsp ?
|
126 |
-
__( 'Content Security Policy is turned on', 'wp-simple-firewall' )
|
127 |
-
: __( "Content Security Policies aren't active", 'wp-simple-firewall' ),
|
128 |
-
'weight' => 1,
|
129 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_content_security_policy' ),
|
130 |
-
];
|
131 |
-
}
|
132 |
-
|
133 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
134 |
-
return $aAllData;
|
135 |
-
}
|
136 |
-
|
137 |
/**
|
138 |
* @return string
|
139 |
*/
|
86 |
$oOpts->setOpt( 'xcsp_hosts', array_unique( $aValidDomains ) );
|
87 |
}
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
/**
|
90 |
* @return string
|
91 |
*/
|
src/features/insights.php
CHANGED
@@ -70,10 +70,10 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
70 |
|
71 |
/** @var ICWP_WPSF_FeatureHandler_UserManagement $oModUsers */
|
72 |
$oModUsers = $oCon->getModule( 'user_management' );
|
73 |
-
/** @var
|
74 |
-
$
|
75 |
-
/** @var
|
76 |
-
$
|
77 |
|
78 |
$oModPlugin = $oCon->getModule_Plugin();
|
79 |
$oTourManager = $oModPlugin->getTourManager();
|
@@ -97,6 +97,8 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
97 |
'flags' => [],
|
98 |
'strings' => [
|
99 |
'table_title' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
|
|
|
|
100 |
'title_filter_form' => __( 'Audit Trail Filters', 'wp-simple-firewall' ),
|
101 |
'username_ignores' => __( "Providing a username will cause the 'logged-in' filter to be ignored.", 'wp-simple-firewall' ),
|
102 |
'exclude_your_ip' => __( 'Exclude Your Current IP', 'wp-simple-firewall' ),
|
@@ -111,6 +113,9 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
111 |
'unique_ips' => $oAuditSelect->getDistinctIps(),
|
112 |
'unique_users' => $oAuditSelect->getDistinctUsernames(),
|
113 |
],
|
|
|
|
|
|
|
114 |
];
|
115 |
break;
|
116 |
|
@@ -223,11 +228,11 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
223 |
break;
|
224 |
|
225 |
case 'license':
|
226 |
-
$aData = $
|
227 |
break;
|
228 |
|
229 |
case 'scans':
|
230 |
-
$aData = $
|
231 |
break;
|
232 |
|
233 |
case 'importexport':
|
@@ -279,7 +284,6 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
279 |
$aData = [
|
280 |
'vars' => [
|
281 |
'config_cards' => $this->getConfigCardsData(),
|
282 |
-
'summary' => $this->getInsightsModsSummary(),
|
283 |
'insight_events' => $this->getRecentEvents(),
|
284 |
'insight_notices' => $aSecNotices,
|
285 |
'insight_notices_count' => $nNoticesCount,
|
@@ -331,7 +335,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
331 |
'notes' => __( 'Notes', 'wp-simple-firewall' ),
|
332 |
// 'reports' => __( 'Reports', 'wp-simple-firewall' ),
|
333 |
'importexport' => sprintf( '%s/%s', __( 'Import', 'wp-simple-firewall' ), __( 'Export', 'wp-simple-firewall' ) ),
|
334 |
-
// 'debug' => __( 'Debug', 'wp-simple-firewall' ),
|
335 |
];
|
336 |
if ( $bIsPro ) {
|
337 |
unset( $aTopNav[ 'license' ] );
|
@@ -350,27 +354,29 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
350 |
|
351 |
$aSearchSelect = [];
|
352 |
$aSettingsSubNav = [];
|
353 |
-
foreach ( $this->getModulesSummaryData() as $
|
354 |
-
$
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
|
|
360 |
|
361 |
-
|
|
|
362 |
}
|
363 |
-
$aTopNav[ 'settings' ][ 'subnavs' ] = $aSettingsSubNav;
|
364 |
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
|
|
370 |
|
371 |
-
$
|
372 |
-
$aData = $
|
373 |
-
$this->getBaseDisplayData(),
|
374 |
[
|
375 |
'classes' => [
|
376 |
'page_container' => 'page-insights page-'.$sNavSection
|
@@ -404,23 +410,23 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
404 |
|
405 |
if ( $this->isThisModulePage() ) {
|
406 |
|
407 |
-
$
|
408 |
-
$aStdDepsJs = [ $
|
409 |
$sNav = Services::Request()->query( 'inav', 'overview' );
|
410 |
|
411 |
-
$oModPlugin = $
|
412 |
$oTourManager = $oModPlugin->getTourManager();
|
413 |
switch ( $sNav ) {
|
414 |
|
415 |
case 'importexport':
|
416 |
|
417 |
$sAsset = 'shield-import';
|
418 |
-
$sUnique = $
|
419 |
wp_register_script(
|
420 |
$sUnique,
|
421 |
-
$
|
422 |
$aStdDepsJs,
|
423 |
-
$
|
424 |
false
|
425 |
);
|
426 |
wp_enqueue_script( $sUnique );
|
@@ -436,12 +442,12 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
436 |
array_unshift( $aJsAssets, 'introjs.min.js' );
|
437 |
}
|
438 |
foreach ( $aJsAssets as $sAsset ) {
|
439 |
-
$sUnique = $
|
440 |
wp_register_script(
|
441 |
$sUnique,
|
442 |
-
$
|
443 |
$aDeps,
|
444 |
-
$
|
445 |
false
|
446 |
);
|
447 |
wp_enqueue_script( $sUnique );
|
@@ -454,12 +460,12 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
454 |
array_unshift( $aCssAssets, 'introjs.min.css' );
|
455 |
}
|
456 |
foreach ( $aCssAssets as $sAsset ) {
|
457 |
-
$sUnique = $
|
458 |
wp_register_style(
|
459 |
$sUnique,
|
460 |
-
$
|
461 |
$aDeps,
|
462 |
-
$
|
463 |
false
|
464 |
);
|
465 |
wp_enqueue_style( $sUnique );
|
@@ -477,12 +483,12 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
477 |
case 'users':
|
478 |
|
479 |
$sAsset = 'shield-tables';
|
480 |
-
$sUnique = $
|
481 |
wp_register_script(
|
482 |
$sUnique,
|
483 |
-
$
|
484 |
$aStdDepsJs,
|
485 |
-
$
|
486 |
false
|
487 |
);
|
488 |
wp_enqueue_script( $sUnique );
|
@@ -490,24 +496,24 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
490 |
$aStdDepsJs[] = $sUnique;
|
491 |
if ( $sNav == 'scans' ) {
|
492 |
$sAsset = 'shield-scans';
|
493 |
-
$sUnique = $
|
494 |
wp_register_script(
|
495 |
$sUnique,
|
496 |
-
$
|
497 |
array_unique( $aStdDepsJs ),
|
498 |
-
$
|
499 |
false
|
500 |
);
|
501 |
wp_enqueue_script( $sUnique );
|
502 |
}
|
503 |
|
504 |
if ( $sNav == 'audit' ) {
|
505 |
-
$sUnique = $
|
506 |
wp_register_script(
|
507 |
$sUnique, //TODO: use an includes services for CNDJS
|
508 |
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js',
|
509 |
array_unique( $aStdDepsJs ),
|
510 |
-
$
|
511 |
false
|
512 |
);
|
513 |
wp_enqueue_script( $sUnique );
|
@@ -516,7 +522,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
516 |
$sUnique,
|
517 |
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css',
|
518 |
[],
|
519 |
-
$
|
520 |
false
|
521 |
);
|
522 |
wp_enqueue_style( $sUnique );
|
@@ -526,7 +532,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
526 |
}
|
527 |
|
528 |
wp_localize_script(
|
529 |
-
$
|
530 |
'icwp_wpsf_vars_insights',
|
531 |
[
|
532 |
'strings' => [
|
@@ -568,7 +574,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
568 |
$oStrs = $oEvtsMod->getStrings();
|
569 |
$aEvtNames = $oStrs->getEventNames();
|
570 |
|
571 |
-
|
572 |
'ajax' => [
|
573 |
'render_chart' => $oEvtsMod->getAjaxActionData( 'render_chart', true ),
|
574 |
],
|
@@ -588,61 +594,57 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
588 |
)
|
589 |
],
|
590 |
];
|
591 |
-
return $aData;
|
592 |
-
}
|
593 |
-
|
594 |
-
/**
|
595 |
-
* @return array[]
|
596 |
-
*/
|
597 |
-
protected function getInsightsModsSummary() {
|
598 |
-
$aMods = [];
|
599 |
-
foreach ( $this->getModulesSummaryData() as $aMod ) {
|
600 |
-
if ( !in_array( $aMod[ 'slug' ], [ 'insights' ] ) ) {
|
601 |
-
$aMods[] = $aMod;
|
602 |
-
}
|
603 |
-
}
|
604 |
-
return $aMods;
|
605 |
}
|
606 |
|
607 |
/**
|
608 |
* @return array[]
|
609 |
*/
|
610 |
protected function getConfigCardsData() {
|
611 |
-
|
|
|
|
|
|
|
|
|
612 |
}
|
613 |
|
614 |
/**
|
615 |
* @return array[]
|
616 |
*/
|
617 |
protected function getNotices() {
|
618 |
-
$aAll =
|
619 |
-
$this->
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
]
|
625 |
-
|
626 |
|
627 |
-
//
|
628 |
-
return array_filter(
|
629 |
-
|
630 |
-
[
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
$
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
}
|
647 |
|
648 |
protected function getNoticesSite() {
|
70 |
|
71 |
/** @var ICWP_WPSF_FeatureHandler_UserManagement $oModUsers */
|
72 |
$oModUsers = $oCon->getModule( 'user_management' );
|
73 |
+
/** @var Shield\Modules\HackGuard\UI $UIHackGuard */
|
74 |
+
$UIHackGuard = $oCon->getModule_HackGuard()->getUIHandler();
|
75 |
+
/** @var Shield\Modules\License\UI $UILicense */
|
76 |
+
$UILicense = $oCon->getModule_License()->getUIHandler();
|
77 |
|
78 |
$oModPlugin = $oCon->getModule_Plugin();
|
79 |
$oTourManager = $oModPlugin->getTourManager();
|
97 |
'flags' => [],
|
98 |
'strings' => [
|
99 |
'table_title' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
100 |
+
'sub_title' => __( 'Use the Audit Trail Glossary for help interpreting log entries.', 'wp-simple-firewall' ),
|
101 |
+
'audit_trail_glossary' => __( 'Audit Trail Glossary', 'wp-simple-firewall' ),
|
102 |
'title_filter_form' => __( 'Audit Trail Filters', 'wp-simple-firewall' ),
|
103 |
'username_ignores' => __( "Providing a username will cause the 'logged-in' filter to be ignored.", 'wp-simple-firewall' ),
|
104 |
'exclude_your_ip' => __( 'Exclude Your Current IP', 'wp-simple-firewall' ),
|
113 |
'unique_ips' => $oAuditSelect->getDistinctIps(),
|
114 |
'unique_users' => $oAuditSelect->getDistinctUsernames(),
|
115 |
],
|
116 |
+
'hrefs' => [
|
117 |
+
'audit_trail_glossary' => 'https://shsec.io/audittrailglossary',
|
118 |
+
],
|
119 |
];
|
120 |
break;
|
121 |
|
228 |
break;
|
229 |
|
230 |
case 'license':
|
231 |
+
$aData = $UILicense->buildInsightsVars();
|
232 |
break;
|
233 |
|
234 |
case 'scans':
|
235 |
+
$aData = $UIHackGuard->buildInsightsVars();
|
236 |
break;
|
237 |
|
238 |
case 'importexport':
|
284 |
$aData = [
|
285 |
'vars' => [
|
286 |
'config_cards' => $this->getConfigCardsData(),
|
|
|
287 |
'insight_events' => $this->getRecentEvents(),
|
288 |
'insight_notices' => $aSecNotices,
|
289 |
'insight_notices_count' => $nNoticesCount,
|
335 |
'notes' => __( 'Notes', 'wp-simple-firewall' ),
|
336 |
// 'reports' => __( 'Reports', 'wp-simple-firewall' ),
|
337 |
'importexport' => sprintf( '%s/%s', __( 'Import', 'wp-simple-firewall' ), __( 'Export', 'wp-simple-firewall' ) ),
|
338 |
+
// 'debug' => __( 'Debug', 'wp-simple-firewall' ),
|
339 |
];
|
340 |
if ( $bIsPro ) {
|
341 |
unset( $aTopNav[ 'license' ] );
|
354 |
|
355 |
$aSearchSelect = [];
|
356 |
$aSettingsSubNav = [];
|
357 |
+
foreach ( $this->getModulesSummaryData() as $slug => $summary ) {
|
358 |
+
if ( $summary[ 'show_mod_opts' ] ) {
|
359 |
+
$aSettingsSubNav[ $slug ] = [
|
360 |
+
'href' => add_query_arg( [ 'subnav' => $slug ], $aTopNav[ 'settings' ][ 'href' ] ),
|
361 |
+
'name' => $summary[ 'name' ],
|
362 |
+
'active' => $slug === $sSubNavSection,
|
363 |
+
'slug' => $slug
|
364 |
+
];
|
365 |
|
366 |
+
$aSearchSelect[ $summary[ 'name' ] ] = $summary[ 'options' ];
|
367 |
+
}
|
368 |
}
|
|
|
369 |
|
370 |
+
if ( empty( $aSettingsSubNav ) ) {
|
371 |
+
unset( $aTopNav[ 'settings' ] );
|
372 |
+
}
|
373 |
+
else {
|
374 |
+
$aTopNav[ 'settings' ][ 'subnavs' ] = $aSettingsSubNav;
|
375 |
+
}
|
376 |
|
377 |
+
$DP = Services::DataManipulation();
|
378 |
+
$aData = $DP->mergeArraysRecursive(
|
379 |
+
$this->getUIHandler()->getBaseDisplayData(),
|
380 |
[
|
381 |
'classes' => [
|
382 |
'page_container' => 'page-insights page-'.$sNavSection
|
410 |
|
411 |
if ( $this->isThisModulePage() ) {
|
412 |
|
413 |
+
$con = $this->getCon();
|
414 |
+
$aStdDepsJs = [ $con->prefix( 'plugin' ) ];
|
415 |
$sNav = Services::Request()->query( 'inav', 'overview' );
|
416 |
|
417 |
+
$oModPlugin = $con->getModule_Plugin();
|
418 |
$oTourManager = $oModPlugin->getTourManager();
|
419 |
switch ( $sNav ) {
|
420 |
|
421 |
case 'importexport':
|
422 |
|
423 |
$sAsset = 'shield-import';
|
424 |
+
$sUnique = $con->prefix( $sAsset );
|
425 |
wp_register_script(
|
426 |
$sUnique,
|
427 |
+
$con->getPluginUrl_Js( $sAsset ),
|
428 |
$aStdDepsJs,
|
429 |
+
$con->getVersion(),
|
430 |
false
|
431 |
);
|
432 |
wp_enqueue_script( $sUnique );
|
442 |
array_unshift( $aJsAssets, 'introjs.min.js' );
|
443 |
}
|
444 |
foreach ( $aJsAssets as $sAsset ) {
|
445 |
+
$sUnique = $con->prefix( $sAsset );
|
446 |
wp_register_script(
|
447 |
$sUnique,
|
448 |
+
$con->getPluginUrl_Js( $sAsset ),
|
449 |
$aDeps,
|
450 |
+
$con->getVersion(),
|
451 |
false
|
452 |
);
|
453 |
wp_enqueue_script( $sUnique );
|
460 |
array_unshift( $aCssAssets, 'introjs.min.css' );
|
461 |
}
|
462 |
foreach ( $aCssAssets as $sAsset ) {
|
463 |
+
$sUnique = $con->prefix( $sAsset );
|
464 |
wp_register_style(
|
465 |
$sUnique,
|
466 |
+
$con->getPluginUrl_Css( $sAsset ),
|
467 |
$aDeps,
|
468 |
+
$con->getVersion(),
|
469 |
false
|
470 |
);
|
471 |
wp_enqueue_style( $sUnique );
|
483 |
case 'users':
|
484 |
|
485 |
$sAsset = 'shield-tables';
|
486 |
+
$sUnique = $con->prefix( $sAsset );
|
487 |
wp_register_script(
|
488 |
$sUnique,
|
489 |
+
$con->getPluginUrl_Js( $sAsset ),
|
490 |
$aStdDepsJs,
|
491 |
+
$con->getVersion(),
|
492 |
false
|
493 |
);
|
494 |
wp_enqueue_script( $sUnique );
|
496 |
$aStdDepsJs[] = $sUnique;
|
497 |
if ( $sNav == 'scans' ) {
|
498 |
$sAsset = 'shield-scans';
|
499 |
+
$sUnique = $con->prefix( $sAsset );
|
500 |
wp_register_script(
|
501 |
$sUnique,
|
502 |
+
$con->getPluginUrl_Js( $sAsset ),
|
503 |
array_unique( $aStdDepsJs ),
|
504 |
+
$con->getVersion(),
|
505 |
false
|
506 |
);
|
507 |
wp_enqueue_script( $sUnique );
|
508 |
}
|
509 |
|
510 |
if ( $sNav == 'audit' ) {
|
511 |
+
$sUnique = $con->prefix( 'datepicker' );
|
512 |
wp_register_script(
|
513 |
$sUnique, //TODO: use an includes services for CNDJS
|
514 |
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js',
|
515 |
array_unique( $aStdDepsJs ),
|
516 |
+
$con->getVersion(),
|
517 |
false
|
518 |
);
|
519 |
wp_enqueue_script( $sUnique );
|
522 |
$sUnique,
|
523 |
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css',
|
524 |
[],
|
525 |
+
$con->getVersion(),
|
526 |
false
|
527 |
);
|
528 |
wp_enqueue_style( $sUnique );
|
532 |
}
|
533 |
|
534 |
wp_localize_script(
|
535 |
+
$con->prefix( 'plugin' ),
|
536 |
'icwp_wpsf_vars_insights',
|
537 |
[
|
538 |
'strings' => [
|
574 |
$oStrs = $oEvtsMod->getStrings();
|
575 |
$aEvtNames = $oStrs->getEventNames();
|
576 |
|
577 |
+
return [
|
578 |
'ajax' => [
|
579 |
'render_chart' => $oEvtsMod->getAjaxActionData( 'render_chart', true ),
|
580 |
],
|
594 |
)
|
595 |
],
|
596 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
}
|
598 |
|
599 |
/**
|
600 |
* @return array[]
|
601 |
*/
|
602 |
protected function getConfigCardsData() {
|
603 |
+
$data = [];
|
604 |
+
foreach ( $this->getCon()->modules as $mod ) {
|
605 |
+
$data[ $mod->getSlug() ] = $mod->getUIHandler()->getInsightsConfigCardData();
|
606 |
+
}
|
607 |
+
return array_filter( $data );
|
608 |
}
|
609 |
|
610 |
/**
|
611 |
* @return array[]
|
612 |
*/
|
613 |
protected function getNotices() {
|
614 |
+
$aAll = [
|
615 |
+
'plugins' => $this->getNoticesPlugins(),
|
616 |
+
'themes' => $this->getNoticesThemes(),
|
617 |
+
'core' => $this->getNoticesCore(),
|
618 |
+
];
|
619 |
+
foreach ( $this->getCon()->modules as $module ) {
|
620 |
+
$aAll[ $module->getSlug() ] = $module->getUIHandler()->getInsightsNoticesData();
|
621 |
+
}
|
622 |
|
623 |
+
// remove empties, add a count, then order.
|
624 |
+
return array_filter( array_merge(
|
625 |
+
[
|
626 |
+
'plugin' => [],
|
627 |
+
'admin_access_restriction' => [],
|
628 |
+
'hack_protect' => [],
|
629 |
+
'core' => [],
|
630 |
+
'plugins' => [],
|
631 |
+
'themes' => [],
|
632 |
+
'user_management' => [],
|
633 |
+
'lockdown' => [],
|
634 |
+
],
|
635 |
+
array_map(
|
636 |
+
function ( $notices ) {
|
637 |
+
$notices[ 'count' ] = count( $notices[ 'messages' ] );
|
638 |
+
return $notices;
|
639 |
+
},
|
640 |
+
array_filter(
|
641 |
+
$aAll,
|
642 |
+
function ( $notices ) {
|
643 |
+
return !empty( $notices[ 'messages' ] );
|
644 |
+
}
|
645 |
+
)
|
646 |
+
)
|
647 |
+
) );
|
648 |
}
|
649 |
|
650 |
protected function getNoticesSite() {
|
src/features/ips.php
CHANGED
@@ -107,40 +107,6 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
107 |
return $this->oOffenseTracker;
|
108 |
}
|
109 |
|
110 |
-
/**
|
111 |
-
* @param string $sSection
|
112 |
-
* @return array
|
113 |
-
*/
|
114 |
-
protected function getSectionWarnings( $sSection ) {
|
115 |
-
$aWarnings = [];
|
116 |
-
|
117 |
-
/** @var IPs\Options $oOpts */
|
118 |
-
$oOpts = $this->getOptions();
|
119 |
-
|
120 |
-
switch ( $sSection ) {
|
121 |
-
|
122 |
-
case 'section_auto_black_list':
|
123 |
-
if ( !$oOpts->isEnabledAutoBlackList() ) {
|
124 |
-
$aWarnings[] = sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ), __( "IP blocking is turned-off because the offenses limit is set to 0.", 'wp-simple-firewall' ) );
|
125 |
-
}
|
126 |
-
break;
|
127 |
-
|
128 |
-
case 'section_behaviours':
|
129 |
-
case 'section_probes':
|
130 |
-
case 'section_logins':
|
131 |
-
if ( !$oOpts->isEnabledAutoBlackList() ) {
|
132 |
-
$aWarnings[] = __( "Since the offenses limit is set to 0, these options have no effect.", 'wp-simple-firewall' );
|
133 |
-
}
|
134 |
-
|
135 |
-
if ( $sSection == 'section_behaviours' && strlen( Services::Request()->getUserAgent() ) == 0 ) {
|
136 |
-
$aWarnings[] = __( "Your User Agent appears to be empty. We recommend not turning on this option.", 'wp-simple-firewall' );
|
137 |
-
}
|
138 |
-
break;
|
139 |
-
}
|
140 |
-
|
141 |
-
return $aWarnings;
|
142 |
-
}
|
143 |
-
|
144 |
/**
|
145 |
* @param string $sOptKey
|
146 |
* @return string
|
@@ -181,8 +147,6 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
181 |
parent::onPluginShutdown();
|
182 |
}
|
183 |
|
184 |
-
/**
|
185 |
-
*/
|
186 |
protected function addFilterIpsToWhiteList() {
|
187 |
$aIps = [];
|
188 |
$oSp = Services::ServiceProviders();
|
107 |
return $this->oOffenseTracker;
|
108 |
}
|
109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
/**
|
111 |
* @param string $sOptKey
|
112 |
* @return string
|
147 |
parent::onPluginShutdown();
|
148 |
}
|
149 |
|
|
|
|
|
150 |
protected function addFilterIpsToWhiteList() {
|
151 |
$aIps = [];
|
152 |
$oSp = Services::ServiceProviders();
|
src/features/license.php
CHANGED
@@ -43,85 +43,6 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
43 |
return $this->oWpHashesTokenManager;
|
44 |
}
|
45 |
|
46 |
-
/**
|
47 |
-
* @return bool
|
48 |
-
*/
|
49 |
-
protected function isEnabledForUiSummary() {
|
50 |
-
return $this->getLicenseHandler()->hasValidWorkingLicense();
|
51 |
-
}
|
52 |
-
|
53 |
-
public function buildInsightsVars() {
|
54 |
-
$oWp = Services::WpGeneral();
|
55 |
-
$oCon = $this->getCon();
|
56 |
-
$oCarbon = Services::Request()->carbon();
|
57 |
-
|
58 |
-
$oCurrent = $this->getLicenseHandler()->getLicense();
|
59 |
-
|
60 |
-
$nExpiresAt = $oCurrent->getExpiresAt();
|
61 |
-
if ( $nExpiresAt > 0 && $nExpiresAt != PHP_INT_MAX ) {
|
62 |
-
$sExpiresAt = $oCarbon->setTimestamp( $nExpiresAt )->diffForHumans()
|
63 |
-
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nExpiresAt ) );
|
64 |
-
}
|
65 |
-
else {
|
66 |
-
$sExpiresAt = 'n/a';
|
67 |
-
}
|
68 |
-
|
69 |
-
$nLastReqAt = $oCurrent->last_request_at;
|
70 |
-
if ( empty( $nLastReqAt ) ) {
|
71 |
-
$sChecked = __( 'Never', 'wp-simple-firewall' );
|
72 |
-
}
|
73 |
-
else {
|
74 |
-
$sChecked = $oCarbon->setTimestamp( $nLastReqAt )->diffForHumans()
|
75 |
-
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nLastReqAt ) );
|
76 |
-
}
|
77 |
-
$aLicenseTableVars = [
|
78 |
-
'product_name' => $oCurrent->is_central ?
|
79 |
-
$this->getDef( 'license_item_name_sc' ) :
|
80 |
-
$this->getDef( 'license_item_name' ),
|
81 |
-
'license_active' => $this->getLicenseHandler()->hasValidWorkingLicense() ?
|
82 |
-
__( '✔', 'wp-simple-firewall' ) : __( '✖', 'wp-simple-firewall' ),
|
83 |
-
'license_expires' => $sExpiresAt,
|
84 |
-
'license_email' => $oCurrent->customer_email,
|
85 |
-
'last_checked' => $sChecked,
|
86 |
-
'last_errors' => $this->hasLastErrors() ? $this->getLastErrors( true ) : '',
|
87 |
-
'wphashes_token' => $this->getWpHashesTokenManager()->hasToken() ?
|
88 |
-
__( '✔', 'wp-simple-firewall' ) : __( '✖', 'wp-simple-firewall' ),
|
89 |
-
'installation_id' => $oCon->getSiteInstallationId(),
|
90 |
-
];
|
91 |
-
return [
|
92 |
-
'vars' => [
|
93 |
-
'license_table' => $aLicenseTableVars,
|
94 |
-
'activation_url' => $oWp->getHomeUrl(),
|
95 |
-
'error' => $this->getLastErrors( true )
|
96 |
-
],
|
97 |
-
'inputs' => [
|
98 |
-
'license_key' => [
|
99 |
-
'name' => $oCon->prefixOption( 'license_key' ),
|
100 |
-
'maxlength' => $this->getDef( 'license_key_length' ),
|
101 |
-
]
|
102 |
-
],
|
103 |
-
'ajax' => [
|
104 |
-
'license_handling' => $this->getAjaxActionData( 'license_handling' ),
|
105 |
-
'connection_debug' => $this->getAjaxActionData( 'connection_debug' )
|
106 |
-
],
|
107 |
-
'aHrefs' => [
|
108 |
-
'shield_pro_url' => 'https://shsec.io/shieldpro',
|
109 |
-
'shield_pro_more_info_url' => 'https://shsec.io/shld1',
|
110 |
-
'iframe_url' => $this->getDef( 'landing_page_url' ),
|
111 |
-
'keyless_cp' => $this->getDef( 'keyless_cp' ),
|
112 |
-
],
|
113 |
-
'flags' => [
|
114 |
-
'show_ads' => false,
|
115 |
-
'button_enabled_check' => true,
|
116 |
-
'show_standard_options' => false,
|
117 |
-
'show_alt_content' => true,
|
118 |
-
'is_pro' => $this->isPremium(),
|
119 |
-
'has_error' => $this->hasLastErrors()
|
120 |
-
],
|
121 |
-
'strings' => $this->getStrings()->getDisplayStrings(),
|
122 |
-
];
|
123 |
-
}
|
124 |
-
|
125 |
protected function redirectToInsightsSubPage() {
|
126 |
Services::Response()->redirect(
|
127 |
$this->getCon()->getModule_Insights()->getUrl_AdminPage(),
|
43 |
return $this->oWpHashesTokenManager;
|
44 |
}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
protected function redirectToInsightsSubPage() {
|
47 |
Services::Response()->redirect(
|
48 |
$this->getCon()->getModule_Insights()->getUrl_AdminPage(),
|
src/features/lockdown.php
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
7 |
|
8 |
/**
|
9 |
* @return string[]
|
|
|
10 |
*/
|
11 |
private function getRestApiAnonymousExclusions() {
|
12 |
$aExcl = $this->getOpt( 'api_namespace_exclusions' );
|
@@ -17,15 +17,18 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
-
* @param string $
|
21 |
* @return bool
|
22 |
*/
|
23 |
-
public function isPermittedAnonRestApiNamespace( $
|
24 |
-
|
|
|
|
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
* @return bool
|
|
|
29 |
*/
|
30 |
public function isOptFileEditingDisabled() {
|
31 |
return $this->isOpt( 'disable_file_editing', 'Y' );
|
@@ -33,6 +36,7 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
33 |
|
34 |
/**
|
35 |
* @return bool
|
|
|
36 |
*/
|
37 |
public function isRestApiAnonymousAccessDisabled() {
|
38 |
return $this->isOpt( 'disable_anonymous_restapi', 'Y' );
|
@@ -40,6 +44,7 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
40 |
|
41 |
/**
|
42 |
* @return bool
|
|
|
43 |
*/
|
44 |
public function isXmlrpcDisabled() {
|
45 |
return $this->isOpt( 'disable_xmlrpc', 'Y' );
|
@@ -53,95 +58,12 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
53 |
* @return $this
|
54 |
*/
|
55 |
private function cleanApiExclusions() {
|
56 |
-
|
|
|
|
|
57 |
return $this->setOpt( 'api_namespace_exclusions', $aExt );
|
58 |
}
|
59 |
|
60 |
-
/**
|
61 |
-
* @param array $aAllNotices
|
62 |
-
* @return array
|
63 |
-
*/
|
64 |
-
public function addInsightsNoticeData( $aAllNotices ) {
|
65 |
-
$aNotices = [
|
66 |
-
'title' => __( 'WP Lockdown', 'wp-simple-firewall' ),
|
67 |
-
'messages' => []
|
68 |
-
];
|
69 |
-
|
70 |
-
{ //edit plugins
|
71 |
-
$bEditingDisabled = $this->isOptFileEditingDisabled() || !current_user_can( 'edit_plugins' );
|
72 |
-
if ( !$bEditingDisabled ) { //assumes current user is admin
|
73 |
-
$aNotices[ 'messages' ][ 'disallow_file_edit' ] = [
|
74 |
-
'title' => __( 'File Editing via WP', 'wp-simple-firewall' ),
|
75 |
-
'message' => __( 'Direct editing of plugin/theme files is permitted.', 'wp-simple-firewall' ),
|
76 |
-
'href' => $this->getUrl_DirectLinkToOption( 'disable_file_editing' ),
|
77 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
78 |
-
'rec' => __( 'WP Plugin file editing should be disabled.', 'wp-simple-firewall' )
|
79 |
-
];
|
80 |
-
}
|
81 |
-
}
|
82 |
-
|
83 |
-
$aNotices[ 'count' ] = count( $aNotices[ 'messages' ] );
|
84 |
-
|
85 |
-
$aAllNotices[ 'lockdown' ] = $aNotices;
|
86 |
-
return $aAllNotices;
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* @param array $aAllData
|
91 |
-
* @return array
|
92 |
-
*/
|
93 |
-
public function addInsightsConfigData( $aAllData ) {
|
94 |
-
$aThis = [
|
95 |
-
'strings' => [
|
96 |
-
'title' => __( 'WordPress Lockdown', 'wp-simple-firewall' ),
|
97 |
-
'sub' => __( 'Restrict WP Functionality e.g. XMLRPC & REST API', 'wp-simple-firewall' ),
|
98 |
-
],
|
99 |
-
'key_opts' => [],
|
100 |
-
'href_options' => $this->getUrl_AdminPage()
|
101 |
-
];
|
102 |
-
|
103 |
-
if ( !$this->isModOptEnabled() ) {
|
104 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
105 |
-
}
|
106 |
-
else {
|
107 |
-
$bEditingDisabled = $this->isOptFileEditingDisabled() || !current_user_can( 'edit_plugins' );
|
108 |
-
$aThis[ 'key_opts' ][ 'editing' ] = [
|
109 |
-
'name' => __( 'File Editing via WP', 'wp-simple-firewall' ),
|
110 |
-
'enabled' => $bEditingDisabled,
|
111 |
-
'summary' => $bEditingDisabled ?
|
112 |
-
__( 'File editing is disabled', 'wp-simple-firewall' )
|
113 |
-
: __( "File editing is permitted through WP admin", 'wp-simple-firewall' ),
|
114 |
-
'weight' => 2,
|
115 |
-
'href' => $this->getUrl_DirectLinkToOption( 'disable_file_editing' ),
|
116 |
-
];
|
117 |
-
|
118 |
-
$bXml = $this->isXmlrpcDisabled();
|
119 |
-
$aThis[ 'key_opts' ][ 'xml' ] = [
|
120 |
-
'name' => __( 'XML-RPC', 'wp-simple-firewall' ),
|
121 |
-
'enabled' => $bXml,
|
122 |
-
'summary' => $bXml ?
|
123 |
-
__( 'XML-RPC is disabled', 'wp-simple-firewall' )
|
124 |
-
: __( "XML-RPC is not blocked", 'wp-simple-firewall' ),
|
125 |
-
'weight' => 1,
|
126 |
-
'href' => $this->getUrl_DirectLinkToOption( 'disable_xmlrpc' ),
|
127 |
-
];
|
128 |
-
|
129 |
-
$bApi = $this->isRestApiAnonymousAccessDisabled();
|
130 |
-
$aThis[ 'key_opts' ][ 'api' ] = [
|
131 |
-
'name' => __( 'REST API', 'wp-simple-firewall' ),
|
132 |
-
'enabled' => $bApi,
|
133 |
-
'summary' => $bApi ?
|
134 |
-
__( 'Anonymous REST API is disabled', 'wp-simple-firewall' )
|
135 |
-
: __( "Anonymous REST API is allowed", 'wp-simple-firewall' ),
|
136 |
-
'weight' => 1,
|
137 |
-
'href' => $this->getUrl_DirectLinkToOption( 'disable_anonymous_restapi' ),
|
138 |
-
];
|
139 |
-
}
|
140 |
-
|
141 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
142 |
-
return $aAllData;
|
143 |
-
}
|
144 |
-
|
145 |
/**
|
146 |
* @return string
|
147 |
*/
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
4 |
|
5 |
class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
6 |
|
7 |
/**
|
8 |
* @return string[]
|
9 |
+
* @deprecated 9.2.0
|
10 |
*/
|
11 |
private function getRestApiAnonymousExclusions() {
|
12 |
$aExcl = $this->getOpt( 'api_namespace_exclusions' );
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
+
* @param string $namespace
|
21 |
* @return bool
|
22 |
*/
|
23 |
+
public function isPermittedAnonRestApiNamespace( $namespace ) {
|
24 |
+
/** @var Shield\Modules\Lockdown\Options $opts */
|
25 |
+
$opts = $this->getOptions();
|
26 |
+
return in_array( $namespace, $opts->getRestApiAnonymousExclusions() );
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
* @return bool
|
31 |
+
* @deprecated 9.2.0
|
32 |
*/
|
33 |
public function isOptFileEditingDisabled() {
|
34 |
return $this->isOpt( 'disable_file_editing', 'Y' );
|
36 |
|
37 |
/**
|
38 |
* @return bool
|
39 |
+
* @deprecated 9.2.0
|
40 |
*/
|
41 |
public function isRestApiAnonymousAccessDisabled() {
|
42 |
return $this->isOpt( 'disable_anonymous_restapi', 'Y' );
|
44 |
|
45 |
/**
|
46 |
* @return bool
|
47 |
+
* @deprecated 9.2.0
|
48 |
*/
|
49 |
public function isXmlrpcDisabled() {
|
50 |
return $this->isOpt( 'disable_xmlrpc', 'Y' );
|
58 |
* @return $this
|
59 |
*/
|
60 |
private function cleanApiExclusions() {
|
61 |
+
/** @var Shield\Modules\Lockdown\Options $opts */
|
62 |
+
$opts = $this->getOptions();
|
63 |
+
$aExt = $this->cleanStringArray( $opts->getRestApiAnonymousExclusions(), '#[^a-z0-9_-]#i' );
|
64 |
return $this->setOpt( 'api_namespace_exclusions', $aExt );
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
/**
|
68 |
* @return string
|
69 |
*/
|
src/features/login_protect.php
CHANGED
@@ -128,8 +128,6 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
128 |
->sendEmailWithWrap( $sEmail, $sEmailSubject, $aMessage );
|
129 |
}
|
130 |
|
131 |
-
/**
|
132 |
-
*/
|
133 |
private function cleanLoginUrlPath() {
|
134 |
$sCustomLoginPath = $this->getCustomLoginPath();
|
135 |
if ( !empty( $sCustomLoginPath ) ) {
|
@@ -274,7 +272,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
274 |
* @return string
|
275 |
*/
|
276 |
public function getLoginIntentRequestFlag() {
|
277 |
-
return $this->prefix( 'login-intent-request' );
|
278 |
}
|
279 |
|
280 |
/**
|
@@ -307,55 +305,11 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
307 |
return $this->setOpt( 'enable_login_gasp_check', $bEnabled ? 'Y' : 'N' );
|
308 |
}
|
309 |
|
310 |
-
/**
|
311 |
-
* @param string $sSection
|
312 |
-
* @return array
|
313 |
-
*/
|
314 |
-
protected function getSectionWarnings( $sSection ) {
|
315 |
-
$aWarnings = [];
|
316 |
-
|
317 |
-
if ( $sSection == 'section_brute_force_login_protection' && !$this->isPremium() ) {
|
318 |
-
$sIntegration = $this->getPremiumOnlyIntegration();
|
319 |
-
if ( !empty( $sIntegration ) ) {
|
320 |
-
$aWarnings[] = sprintf( __( 'Support for login protection with %s is a Pro-only feature.', 'wp-simple-firewall' ), $sIntegration );
|
321 |
-
}
|
322 |
-
}
|
323 |
-
|
324 |
-
if ( $sSection == 'section_2fa_email' ) {
|
325 |
-
$aWarnings[] =
|
326 |
-
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
327 |
-
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
328 |
-
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', __( 'Learn More.', 'wp-simple-firewall' ) );
|
329 |
-
}
|
330 |
-
|
331 |
-
return $aWarnings;
|
332 |
-
}
|
333 |
-
|
334 |
-
/**
|
335 |
-
* @return string
|
336 |
-
*/
|
337 |
-
protected function getPremiumOnlyIntegration() {
|
338 |
-
$aIntegrations = [
|
339 |
-
'WooCommerce' => 'WooCommerce',
|
340 |
-
'Easy_Digital_Downloads' => 'Easy Digital Downloads',
|
341 |
-
'BuddyPress' => 'BuddyPress',
|
342 |
-
];
|
343 |
-
|
344 |
-
$sIntegration = '';
|
345 |
-
foreach ( $aIntegrations as $sInt => $sName ) {
|
346 |
-
if ( class_exists( $sInt ) ) {
|
347 |
-
$sIntegration = $sName;
|
348 |
-
break;
|
349 |
-
}
|
350 |
-
}
|
351 |
-
return $sIntegration;
|
352 |
-
}
|
353 |
-
|
354 |
public function insertCustomJsVars_Admin() {
|
355 |
parent::insertCustomJsVars_Admin();
|
356 |
|
357 |
wp_localize_script(
|
358 |
-
$this->prefix( 'global-plugin' ),
|
359 |
'icwp_wpsf_vars_lg',
|
360 |
[
|
361 |
'ajax_gen_backup_codes' => $this->getAjaxActionData( 'gen_backup_codes' ),
|
@@ -366,76 +320,6 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
366 |
wp_enqueue_style( 'wp-jquery-ui-dialog' );
|
367 |
}
|
368 |
|
369 |
-
/**
|
370 |
-
* @param array $aAllData
|
371 |
-
* @return array
|
372 |
-
*/
|
373 |
-
public function addInsightsConfigData( $aAllData ) {
|
374 |
-
/** @var LoginGuard\Options $oOpts */
|
375 |
-
$oOpts = $this->getOptions();
|
376 |
-
$aThis = [
|
377 |
-
'strings' => [
|
378 |
-
'title' => __( 'Login Guard', 'wp-simple-firewall' ),
|
379 |
-
'sub' => __( 'Brute Force Protection & Identity Verification', 'wp-simple-firewall' ),
|
380 |
-
],
|
381 |
-
'key_opts' => [],
|
382 |
-
'href_options' => $this->getUrl_AdminPage()
|
383 |
-
];
|
384 |
-
|
385 |
-
if ( !$this->isModOptEnabled() ) {
|
386 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
387 |
-
}
|
388 |
-
else {
|
389 |
-
$bHasBotCheck = $oOpts->isEnabledGaspCheck() || $this->isEnabledCaptcha();
|
390 |
-
|
391 |
-
$bBotLogin = $bHasBotCheck && $oOpts->isProtectLogin();
|
392 |
-
$bBotRegister = $bHasBotCheck && $oOpts->isProtectRegister();
|
393 |
-
$bBotPassword = $bHasBotCheck && $oOpts->isProtectLostPassword();
|
394 |
-
$aThis[ 'key_opts' ][ 'bot_login' ] = [
|
395 |
-
'name' => __( 'Brute Force Login', 'wp-simple-firewall' ),
|
396 |
-
'enabled' => $bBotLogin,
|
397 |
-
'summary' => $bBotLogin ?
|
398 |
-
__( 'Login forms are protected against bot attacks', 'wp-simple-firewall' )
|
399 |
-
: __( 'Login forms are not protected against brute force bot attacks', 'wp-simple-firewall' ),
|
400 |
-
'weight' => 2,
|
401 |
-
'href' => $this->getUrl_DirectLinkToOption( 'bot_protection_locations' ),
|
402 |
-
];
|
403 |
-
$aThis[ 'key_opts' ][ 'bot_register' ] = [
|
404 |
-
'name' => __( 'Bot User Register', 'wp-simple-firewall' ),
|
405 |
-
'enabled' => $bBotRegister,
|
406 |
-
'summary' => $bBotRegister ?
|
407 |
-
__( 'Registration forms are protected against bot attacks', 'wp-simple-firewall' )
|
408 |
-
: __( 'Registration forms are not protected against automated bots', 'wp-simple-firewall' ),
|
409 |
-
'weight' => 2,
|
410 |
-
'href' => $this->getUrl_DirectLinkToOption( 'bot_protection_locations' ),
|
411 |
-
];
|
412 |
-
$aThis[ 'key_opts' ][ 'bot_password' ] = [
|
413 |
-
'name' => __( 'Brute Force Lost Password', 'wp-simple-firewall' ),
|
414 |
-
'enabled' => $bBotPassword,
|
415 |
-
'summary' => $bBotPassword ?
|
416 |
-
__( 'Lost Password forms are protected against bot attacks', 'wp-simple-firewall' )
|
417 |
-
: __( 'Lost Password forms are not protected against automated bots', 'wp-simple-firewall' ),
|
418 |
-
'weight' => 2,
|
419 |
-
'href' => $this->getUrl_DirectLinkToOption( 'bot_protection_locations' ),
|
420 |
-
];
|
421 |
-
|
422 |
-
$bHas2Fa = $oOpts->isEmailAuthenticationActive()
|
423 |
-
|| $oOpts->isEnabledGoogleAuthenticator() || $oOpts->isEnabledYubikey();
|
424 |
-
$aThis[ 'key_opts' ][ '2fa' ] = [
|
425 |
-
'name' => __( 'Identity Verification', 'wp-simple-firewall' ),
|
426 |
-
'enabled' => $bHas2Fa,
|
427 |
-
'summary' => $bHas2Fa ?
|
428 |
-
__( 'At least 1 2FA option is enabled', 'wp-simple-firewall' )
|
429 |
-
: __( 'No 2FA options, such as Google Authenticator, are active', 'wp-simple-firewall' ),
|
430 |
-
'weight' => 2,
|
431 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_2fa_email' ),
|
432 |
-
];
|
433 |
-
}
|
434 |
-
|
435 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
436 |
-
return $aAllData;
|
437 |
-
}
|
438 |
-
|
439 |
/**
|
440 |
* @return string
|
441 |
*/
|
128 |
->sendEmailWithWrap( $sEmail, $sEmailSubject, $aMessage );
|
129 |
}
|
130 |
|
|
|
|
|
131 |
private function cleanLoginUrlPath() {
|
132 |
$sCustomLoginPath = $this->getCustomLoginPath();
|
133 |
if ( !empty( $sCustomLoginPath ) ) {
|
272 |
* @return string
|
273 |
*/
|
274 |
public function getLoginIntentRequestFlag() {
|
275 |
+
return $this->getCon()->prefix( 'login-intent-request' );
|
276 |
}
|
277 |
|
278 |
/**
|
305 |
return $this->setOpt( 'enable_login_gasp_check', $bEnabled ? 'Y' : 'N' );
|
306 |
}
|
307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
public function insertCustomJsVars_Admin() {
|
309 |
parent::insertCustomJsVars_Admin();
|
310 |
|
311 |
wp_localize_script(
|
312 |
+
$this->getCon()->prefix( 'global-plugin' ),
|
313 |
'icwp_wpsf_vars_lg',
|
314 |
[
|
315 |
'ajax_gen_backup_codes' => $this->getAjaxActionData( 'gen_backup_codes' ),
|
320 |
wp_enqueue_style( 'wp-jquery-ui-dialog' );
|
321 |
}
|
322 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
/**
|
324 |
* @return string
|
325 |
*/
|
src/features/plugin.php
CHANGED
@@ -70,44 +70,14 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
70 |
->checkAll();
|
71 |
}
|
72 |
|
73 |
-
/**
|
74 |
-
* @param string $sSection
|
75 |
-
* @return array
|
76 |
-
*/
|
77 |
-
protected function getSectionWarnings( $sSection ) {
|
78 |
-
$aWarnings = [];
|
79 |
-
|
80 |
-
switch ( $sSection ) {
|
81 |
-
case 'section_third_party_captcha':
|
82 |
-
/** @var Plugin\Options $oOpts */
|
83 |
-
$oOpts = $this->getOptions();
|
84 |
-
if ( $this->getCaptchaCfg()->ready ) {
|
85 |
-
if ( $oOpts->getOpt( 'captcha_checked_at' ) < 0 ) {
|
86 |
-
( new Plugin\Lib\Captcha\CheckCaptchaSettings() )
|
87 |
-
->setMod( $this )
|
88 |
-
->checkAll();
|
89 |
-
}
|
90 |
-
if ( $oOpts->getOpt( 'captcha_checked_at' ) == 0 ) {
|
91 |
-
$aWarnings[] = sprintf(
|
92 |
-
__( "Your captcha key and secret haven't been verified.", 'wp-simple-firewall' ).' '
|
93 |
-
.__( "Please double-check and make sure you haven't mixed them about, and then re-save.", 'wp-simple-firewall' )
|
94 |
-
);
|
95 |
-
}
|
96 |
-
}
|
97 |
-
break;
|
98 |
-
}
|
99 |
-
|
100 |
-
return $aWarnings;
|
101 |
-
}
|
102 |
-
|
103 |
public function deleteAllPluginCrons() {
|
104 |
-
$
|
105 |
$oWpCron = Services::WpCron();
|
106 |
|
107 |
foreach ( $oWpCron->getCrons() as $nKey => $aCronArgs ) {
|
108 |
foreach ( $aCronArgs as $sHook => $aCron ) {
|
109 |
-
if ( strpos( $sHook, $
|
110 |
-
|| strpos( $sHook, $
|
111 |
$oWpCron->deleteCronJob( $sHook );
|
112 |
}
|
113 |
}
|
@@ -225,7 +195,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
225 |
public function getPluginReportEmail() {
|
226 |
$sE = (string)$this->getOpt( 'block_send_email_address' );
|
227 |
if ( $this->isPremium() ) {
|
228 |
-
$sE = apply_filters( $this->prefix( 'report_email' ), $sE );
|
229 |
}
|
230 |
$sE = trim( $sE );
|
231 |
return Services::Data()->validEmail( $sE ) ? $sE : Services::WpGeneral()->getSiteAdminEmail();
|
@@ -576,11 +546,11 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
576 |
public function insertCustomJsVars_Admin() {
|
577 |
parent::insertCustomJsVars_Admin();
|
578 |
|
579 |
-
$
|
580 |
if ( Services::WpPost()->isCurrentPage( 'plugins.php' ) ) {
|
581 |
-
$sFile = $
|
582 |
wp_localize_script(
|
583 |
-
$
|
584 |
'icwp_wpsf_vars_plugin',
|
585 |
[
|
586 |
'file' => $sFile,
|
@@ -597,12 +567,12 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
597 |
}
|
598 |
|
599 |
wp_localize_script(
|
600 |
-
$
|
601 |
'icwp_wpsf_vars_tourmanager',
|
602 |
[ 'ajax' => $this->getAjaxActionData( 'mark_tour_finished' ) ]
|
603 |
);
|
604 |
wp_localize_script(
|
605 |
-
$
|
606 |
'icwp_wpsf_vars_plugin',
|
607 |
[
|
608 |
'strings' => [
|
@@ -613,62 +583,6 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
613 |
);
|
614 |
}
|
615 |
|
616 |
-
/**
|
617 |
-
* @param array $aAllData
|
618 |
-
* @return array
|
619 |
-
*/
|
620 |
-
public function addInsightsConfigData( $aAllData ) {
|
621 |
-
$aThis = [
|
622 |
-
'strings' => [
|
623 |
-
'title' => __( 'General Settings', 'wp-simple-firewall' ),
|
624 |
-
'sub' => sprintf( __( 'General %s Settings', 'wp-simple-firewall' ), $this->getCon()
|
625 |
-
->getHumanName() ),
|
626 |
-
],
|
627 |
-
'key_opts' => [],
|
628 |
-
'href_options' => $this->getUrl_AdminPage()
|
629 |
-
];
|
630 |
-
|
631 |
-
$oOpts = $this->getOptions();
|
632 |
-
if ( $this->isModOptEnabled() ) {
|
633 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
634 |
-
}
|
635 |
-
else {
|
636 |
-
$aThis[ 'key_opts' ][ 'editing' ] = [
|
637 |
-
'name' => __( 'Visitor IP', 'wp-simple-firewall' ),
|
638 |
-
'enabled' => true,
|
639 |
-
'summary' => sprintf( __( 'Visitor IP address source is: %s', 'wp-simple-firewall' ),
|
640 |
-
__( $oOpts->getSelectOptionValueText( 'visitor_address_source' ), 'wp-simple-firewall' ) ),
|
641 |
-
'weight' => 0,
|
642 |
-
'href' => $this->getUrl_DirectLinkToOption( 'visitor_address_source' ),
|
643 |
-
];
|
644 |
-
|
645 |
-
$bHasSupportEmail = Services::Data()->validEmail( $this->getOpt( 'block_send_email_address' ) );
|
646 |
-
$aThis[ 'key_opts' ][ 'reports' ] = [
|
647 |
-
'name' => __( 'Reporting Email', 'wp-simple-firewall' ),
|
648 |
-
'enabled' => $bHasSupportEmail,
|
649 |
-
'summary' => $bHasSupportEmail ?
|
650 |
-
sprintf( __( 'Email address for reports set to: %s', 'wp-simple-firewall' ), $this->getPluginReportEmail() )
|
651 |
-
: sprintf( __( 'No address provided - defaulting to: %s', 'wp-simple-firewall' ), $this->getPluginReportEmail() ),
|
652 |
-
'weight' => 0,
|
653 |
-
'href' => $this->getUrl_DirectLinkToOption( 'block_send_email_address' ),
|
654 |
-
];
|
655 |
-
|
656 |
-
$bRecap = $this->getCaptchaCfg()->ready;
|
657 |
-
$aThis[ 'key_opts' ][ 'recap' ] = [
|
658 |
-
'name' => __( 'CAPTCHA', 'wp-simple-firewall' ),
|
659 |
-
'enabled' => $bRecap,
|
660 |
-
'summary' => $bRecap ?
|
661 |
-
__( 'CAPTCHA keys have been provided', 'wp-simple-firewall' )
|
662 |
-
: __( "CAPTCHA keys haven't been provided", 'wp-simple-firewall' ),
|
663 |
-
'weight' => 1,
|
664 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_third_party_captcha' ),
|
665 |
-
];
|
666 |
-
}
|
667 |
-
|
668 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
669 |
-
return $aAllData;
|
670 |
-
}
|
671 |
-
|
672 |
/**
|
673 |
* @return Shield\Databases\GeoIp\Handler
|
674 |
*/
|
@@ -693,30 +607,6 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
693 |
return $this->oCaptchaEnqueue;
|
694 |
}
|
695 |
|
696 |
-
/**
|
697 |
-
* @param array $aOptParams
|
698 |
-
* @return array
|
699 |
-
*/
|
700 |
-
protected function buildOptionForUi( $aOptParams ) {
|
701 |
-
$aOptParams = parent::buildOptionForUi( $aOptParams );
|
702 |
-
if ( $aOptParams[ 'key' ] === 'visitor_address_source' ) {
|
703 |
-
$aNewOptions = [];
|
704 |
-
$oIPDet = Services::IP()->getIpDetector();
|
705 |
-
foreach ( $aOptParams[ 'value_options' ] as $sValKey => $sSource ) {
|
706 |
-
if ( $sValKey == 'AUTO_DETECT_IP' ) {
|
707 |
-
$aNewOptions[ $sValKey ] = $sSource;
|
708 |
-
}
|
709 |
-
else {
|
710 |
-
$sIPs = implode( ', ', $oIPDet->getIpsFromSource( $sSource ) );
|
711 |
-
$aNewOptions[ $sValKey ] = sprintf( '%s (%s)',
|
712 |
-
$sSource, empty( $sIPs ) ? '-' : $sIPs );
|
713 |
-
}
|
714 |
-
}
|
715 |
-
$aOptParams[ 'value_options' ] = $aNewOptions;
|
716 |
-
}
|
717 |
-
return $aOptParams;
|
718 |
-
}
|
719 |
-
|
720 |
/**
|
721 |
* @return string
|
722 |
*/
|
70 |
->checkAll();
|
71 |
}
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
public function deleteAllPluginCrons() {
|
74 |
+
$con = $this->getCon();
|
75 |
$oWpCron = Services::WpCron();
|
76 |
|
77 |
foreach ( $oWpCron->getCrons() as $nKey => $aCronArgs ) {
|
78 |
foreach ( $aCronArgs as $sHook => $aCron ) {
|
79 |
+
if ( strpos( $sHook, $con->prefix() ) === 0
|
80 |
+
|| strpos( $sHook, $con->prefixOption() ) === 0 ) {
|
81 |
$oWpCron->deleteCronJob( $sHook );
|
82 |
}
|
83 |
}
|
195 |
public function getPluginReportEmail() {
|
196 |
$sE = (string)$this->getOpt( 'block_send_email_address' );
|
197 |
if ( $this->isPremium() ) {
|
198 |
+
$sE = apply_filters( $this->getCon()->prefix( 'report_email' ), $sE );
|
199 |
}
|
200 |
$sE = trim( $sE );
|
201 |
return Services::Data()->validEmail( $sE ) ? $sE : Services::WpGeneral()->getSiteAdminEmail();
|
546 |
public function insertCustomJsVars_Admin() {
|
547 |
parent::insertCustomJsVars_Admin();
|
548 |
|
549 |
+
$con = $this->getCon();
|
550 |
if ( Services::WpPost()->isCurrentPage( 'plugins.php' ) ) {
|
551 |
+
$sFile = $con->getPluginBaseFile();
|
552 |
wp_localize_script(
|
553 |
+
$con->prefix( 'global-plugin' ),
|
554 |
'icwp_wpsf_vars_plugin',
|
555 |
[
|
556 |
'file' => $sFile,
|
567 |
}
|
568 |
|
569 |
wp_localize_script(
|
570 |
+
$con->prefix( 'plugin' ),
|
571 |
'icwp_wpsf_vars_tourmanager',
|
572 |
[ 'ajax' => $this->getAjaxActionData( 'mark_tour_finished' ) ]
|
573 |
);
|
574 |
wp_localize_script(
|
575 |
+
$con->prefix( 'plugin' ),
|
576 |
'icwp_wpsf_vars_plugin',
|
577 |
[
|
578 |
'strings' => [
|
583 |
);
|
584 |
}
|
585 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
/**
|
587 |
* @return Shield\Databases\GeoIp\Handler
|
588 |
*/
|
607 |
return $this->oCaptchaEnqueue;
|
608 |
}
|
609 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
610 |
/**
|
611 |
* @return string
|
612 |
*/
|
src/features/traffic.php
CHANGED
@@ -39,37 +39,6 @@ class ICWP_WPSF_FeatureHandler_Traffic extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
39 |
&& parent::isReadyToExecute();
|
40 |
}
|
41 |
|
42 |
-
/**
|
43 |
-
* @param string $sSection
|
44 |
-
* @return array
|
45 |
-
*/
|
46 |
-
protected function getSectionWarnings( $sSection ) {
|
47 |
-
/** @var Traffic\Options $oOpts */
|
48 |
-
$oOpts = $this->getOptions();
|
49 |
-
|
50 |
-
$aWarnings = [];
|
51 |
-
|
52 |
-
$oIp = Services::IP();
|
53 |
-
if ( !$oIp->isValidIp_PublicRange( $oIp->getRequestIp() ) ) {
|
54 |
-
$aWarnings[] = __( 'Traffic Watcher will not run because visitor IP address detection is not correctly configured.', 'wp-simple-firewall' );
|
55 |
-
}
|
56 |
-
|
57 |
-
switch ( $sSection ) {
|
58 |
-
case 'section_traffic_limiter':
|
59 |
-
if ( $this->isPremium() ) {
|
60 |
-
if ( !$oOpts->isTrafficLoggerEnabled() ) {
|
61 |
-
$aWarnings[] = sprintf( __( '%s may only be enabled if the Traffic Logger feature is also turned on.', 'wp-simple-firewall' ), __( 'Traffic Rate Limiter', 'wp-simple-firewall' ) );
|
62 |
-
}
|
63 |
-
}
|
64 |
-
else {
|
65 |
-
$aWarnings[] = sprintf( __( '%s is a Pro-only feature.', 'wp-simple-firewall' ), __( 'Traffic Rate Limiter', 'wp-simple-firewall' ) );
|
66 |
-
}
|
67 |
-
break;
|
68 |
-
}
|
69 |
-
|
70 |
-
return $aWarnings;
|
71 |
-
}
|
72 |
-
|
73 |
/**
|
74 |
* @return string
|
75 |
*/
|
39 |
&& parent::isReadyToExecute();
|
40 |
}
|
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
/**
|
43 |
* @return string
|
44 |
*/
|
src/features/user_management.php
CHANGED
@@ -35,31 +35,29 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
35 |
}
|
36 |
|
37 |
protected function preProcessOptions() {
|
38 |
-
/** @var UserManagement\Options $
|
39 |
-
$
|
40 |
|
41 |
-
$
|
42 |
|
43 |
-
if ( $
|
44 |
-
$
|
45 |
}
|
46 |
|
47 |
-
$
|
48 |
array_unique( array_filter( array_map(
|
49 |
function ( $sRole ) {
|
50 |
return preg_replace( '#[^\sa-z0-9_-]#i', '', trim( strtolower( $sRole ) ) );
|
51 |
},
|
52 |
-
$
|
53 |
) ) )
|
54 |
);
|
55 |
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
$aChecks[] = 'syntax';
|
60 |
-
}
|
61 |
-
$oOpts->setOpt( 'email_checks', array_unique( $aChecks ) );
|
62 |
}
|
|
|
63 |
}
|
64 |
|
65 |
/**
|
@@ -137,121 +135,6 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
137 |
return $this->setOpt( 'hard_suspended_userids', $aIds );
|
138 |
}
|
139 |
|
140 |
-
/**
|
141 |
-
* @param array $aAllNotices
|
142 |
-
* @return array
|
143 |
-
*/
|
144 |
-
public function addInsightsNoticeData( $aAllNotices ) {
|
145 |
-
/** @var UserManagement\Options $oOpts */
|
146 |
-
$oOpts = $this->getOptions();
|
147 |
-
|
148 |
-
$aNotices = [
|
149 |
-
'title' => __( 'Users', 'wp-simple-firewall' ),
|
150 |
-
'messages' => []
|
151 |
-
];
|
152 |
-
|
153 |
-
{ //admin user
|
154 |
-
$oAdmin = Services::WpUsers()->getUserByUsername( 'admin' );
|
155 |
-
if ( !empty( $oAdmin ) && user_can( $oAdmin, 'manage_options' ) ) {
|
156 |
-
$aNotices[ 'messages' ][ 'admin' ] = [
|
157 |
-
'title' => 'Admin User',
|
158 |
-
'message' => sprintf( __( "Default 'admin' user still available.", 'wp-simple-firewall' ) ),
|
159 |
-
'href' => '',
|
160 |
-
'rec' => __( "Default 'admin' user should be disabled or removed.", 'wp-simple-firewall' )
|
161 |
-
];
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
{//password policies
|
166 |
-
if ( !$oOpts->isPasswordPoliciesEnabled() ) {
|
167 |
-
$aNotices[ 'messages' ][ 'password' ] = [
|
168 |
-
'title' => __( 'Password Policies', 'wp-simple-firewall' ),
|
169 |
-
'message' => __( "Strong password policies are not enforced.", 'wp-simple-firewall' ),
|
170 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_passwords' ),
|
171 |
-
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
172 |
-
'rec' => __( 'Password policies should be turned-on.', 'wp-simple-firewall' )
|
173 |
-
];
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
$aNotices[ 'count' ] = count( $aNotices[ 'messages' ] );
|
178 |
-
|
179 |
-
$aAllNotices[ 'users' ] = $aNotices;
|
180 |
-
return $aAllNotices;
|
181 |
-
}
|
182 |
-
|
183 |
-
/**
|
184 |
-
* @param array $aAllData
|
185 |
-
* @return array
|
186 |
-
*/
|
187 |
-
public function addInsightsConfigData( $aAllData ) {
|
188 |
-
/** @var UserManagement\Options $oOpts */
|
189 |
-
$oOpts = $this->getOptions();
|
190 |
-
|
191 |
-
$aThis = [
|
192 |
-
'strings' => [
|
193 |
-
'title' => __( 'User Management', 'wp-simple-firewall' ),
|
194 |
-
'sub' => __( 'Sessions Control & Password Policies', 'wp-simple-firewall' ),
|
195 |
-
],
|
196 |
-
'key_opts' => [],
|
197 |
-
'href_options' => $this->getUrl_AdminPage()
|
198 |
-
];
|
199 |
-
|
200 |
-
if ( !$this->isModOptEnabled() ) {
|
201 |
-
$aThis[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
202 |
-
}
|
203 |
-
else {
|
204 |
-
$bHasIdle = $oOpts->hasSessionIdleTimeout();
|
205 |
-
$aThis[ 'key_opts' ][ 'idle' ] = [
|
206 |
-
'name' => __( 'Idle Users', 'wp-simple-firewall' ),
|
207 |
-
'enabled' => $bHasIdle,
|
208 |
-
'summary' => $bHasIdle ?
|
209 |
-
sprintf( __( 'Idle sessions are terminated after %s hours', 'wp-simple-firewall' ), $this->getOpt( 'session_idle_timeout_interval' ) )
|
210 |
-
: __( 'Idle sessions wont be terminated', 'wp-simple-firewall' ),
|
211 |
-
'weight' => 2,
|
212 |
-
'href' => $this->getUrl_DirectLinkToOption( 'session_idle_timeout_interval' ),
|
213 |
-
];
|
214 |
-
|
215 |
-
$bLocked = $oOpts->isLockToIp();
|
216 |
-
$aThis[ 'key_opts' ][ 'lock' ] = [
|
217 |
-
'name' => __( 'Lock To IP', 'wp-simple-firewall' ),
|
218 |
-
'enabled' => $bLocked,
|
219 |
-
'summary' => $bLocked ?
|
220 |
-
__( 'Sessions are locked to IP address', 'wp-simple-firewall' )
|
221 |
-
: __( "Sessions aren't locked to IP address", 'wp-simple-firewall' ),
|
222 |
-
'weight' => 1,
|
223 |
-
'href' => $this->getUrl_DirectLinkToOption( 'session_lock_location' ),
|
224 |
-
];
|
225 |
-
|
226 |
-
$bPolicies = $oOpts->isPasswordPoliciesEnabled();
|
227 |
-
|
228 |
-
$bPwned = $bPolicies && $oOpts->isPassPreventPwned();
|
229 |
-
$aThis[ 'key_opts' ][ 'pwned' ] = [
|
230 |
-
'name' => __( 'Pwned Passwords', 'wp-simple-firewall' ),
|
231 |
-
'enabled' => $bPwned,
|
232 |
-
'summary' => $bPwned ?
|
233 |
-
__( 'Pwned passwords are blocked on this site', 'wp-simple-firewall' )
|
234 |
-
: __( 'Pwned passwords are allowed on this site', 'wp-simple-firewall' ),
|
235 |
-
'weight' => 2,
|
236 |
-
'href' => $this->getUrl_DirectLinkToOption( 'pass_prevent_pwned' ),
|
237 |
-
];
|
238 |
-
|
239 |
-
$bIndepthPolices = $bPolicies && $this->isPremium();
|
240 |
-
$aThis[ 'key_opts' ][ 'policies' ] = [
|
241 |
-
'name' => __( 'Password Policies', 'wp-simple-firewall' ),
|
242 |
-
'enabled' => $bIndepthPolices,
|
243 |
-
'summary' => $bIndepthPolices ?
|
244 |
-
__( 'Several password policies are active', 'wp-simple-firewall' )
|
245 |
-
: __( 'Limited or no password polices are active', 'wp-simple-firewall' ),
|
246 |
-
'weight' => 2,
|
247 |
-
'href' => $this->getUrl_DirectLinkToSection( 'section_passwords' ),
|
248 |
-
];
|
249 |
-
}
|
250 |
-
|
251 |
-
$aAllData[ $this->getSlug() ] = $aThis;
|
252 |
-
return $aAllData;
|
253 |
-
}
|
254 |
-
|
255 |
/**
|
256 |
* @return string
|
257 |
*/
|
35 |
}
|
36 |
|
37 |
protected function preProcessOptions() {
|
38 |
+
/** @var UserManagement\Options $opts */
|
39 |
+
$opts = $this->getOptions();
|
40 |
|
41 |
+
$opts->setOpt( 'enable_admin_login_email_notification', implode( ', ', $this->getAdminLoginNotificationEmails() ) );
|
42 |
|
43 |
+
if ( $opts->getIdleTimeoutInterval() > $opts->getMaxSessionTime() ) {
|
44 |
+
$opts->setOpt( 'session_idle_timeout_interval', $opts->getOpt( 'session_timeout_interval' )*24 );
|
45 |
}
|
46 |
|
47 |
+
$opts->setOpt( 'auto_idle_roles',
|
48 |
array_unique( array_filter( array_map(
|
49 |
function ( $sRole ) {
|
50 |
return preg_replace( '#[^\sa-z0-9_-]#i', '', trim( strtolower( $sRole ) ) );
|
51 |
},
|
52 |
+
$opts->getSuspendAutoIdleUserRoles()
|
53 |
) ) )
|
54 |
);
|
55 |
|
56 |
+
$aChecks = $opts->getEmailValidationChecks();
|
57 |
+
if ( !empty( $aChecks ) ) {
|
58 |
+
$aChecks[] = 'syntax';
|
|
|
|
|
|
|
59 |
}
|
60 |
+
$opts->setOpt( 'email_checks', array_unique( $aChecks ) );
|
61 |
}
|
62 |
|
63 |
/**
|
135 |
return $this->setOpt( 'hard_suspended_userids', $aIds );
|
136 |
}
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
/**
|
139 |
* @return string
|
140 |
*/
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -15,7 +15,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
15 |
* @property bool $plugin_deactivating
|
16 |
* @property bool $plugin_deleting
|
17 |
* @property bool $plugin_reset
|
18 |
-
* @property string
|
19 |
* @property string $base_file
|
20 |
* @property string $root_file
|
21 |
* @property bool $user_can_base_permissions
|
@@ -46,11 +46,6 @@ class Controller {
|
|
46 |
*/
|
47 |
protected $bRebuildOptions;
|
48 |
|
49 |
-
/**
|
50 |
-
* @var string
|
51 |
-
*/
|
52 |
-
protected $sForceOffFile;
|
53 |
-
|
54 |
/**
|
55 |
* @var string
|
56 |
*/
|
@@ -218,8 +213,6 @@ class Controller {
|
|
218 |
}
|
219 |
}
|
220 |
|
221 |
-
/**
|
222 |
-
*/
|
223 |
public function adminNoticeDoesNotMeetRequirements() {
|
224 |
$aMessages = $this->getRequirementsMessages();
|
225 |
if ( !empty( $aMessages ) && is_array( $aMessages ) ) {
|
@@ -241,8 +234,6 @@ class Controller {
|
|
241 |
}
|
242 |
}
|
243 |
|
244 |
-
/**
|
245 |
-
*/
|
246 |
public function adminNoticePluginFailedToLoad() {
|
247 |
$aDisplayData = [
|
248 |
'strings' => [
|
@@ -332,8 +323,6 @@ class Controller {
|
|
332 |
return $bSuccess;
|
333 |
}
|
334 |
|
335 |
-
/**
|
336 |
-
*/
|
337 |
protected function doRegisterHooks() {
|
338 |
register_deactivation_hook( $this->getRootFile(), [ $this, 'onWpDeactivatePlugin' ] );
|
339 |
|
@@ -397,8 +386,6 @@ class Controller {
|
|
397 |
);
|
398 |
}
|
399 |
|
400 |
-
/**
|
401 |
-
*/
|
402 |
public function onWpAdminInit() {
|
403 |
add_action( 'admin_bar_menu', [ $this, 'onWpAdminBarMenu' ], 100 );
|
404 |
add_action( 'wp_dashboard_setup', [ $this, 'onWpDashboardSetup' ] );
|
@@ -429,8 +416,6 @@ class Controller {
|
|
429 |
return $aHeaders;
|
430 |
}
|
431 |
|
432 |
-
/**
|
433 |
-
*/
|
434 |
public function onWpInit() {
|
435 |
$this->getMeetsBasePermissions();
|
436 |
add_action( 'wp_enqueue_scripts', [ $this, 'onWpEnqueueFrontendCss' ], 99 );
|
@@ -504,8 +489,6 @@ class Controller {
|
|
504 |
->run();
|
505 |
}
|
506 |
|
507 |
-
/**
|
508 |
-
*/
|
509 |
public function onWpAdminMenu() {
|
510 |
if ( $this->isValidAdminArea() ) {
|
511 |
$this->createPluginMenu();
|
@@ -517,7 +500,8 @@ class Controller {
|
|
517 |
*/
|
518 |
public function onWpAdminBarMenu( $oAdminBar ) {
|
519 |
$bShow = apply_filters( $this->prefix( 'show_admin_bar_menu' ),
|
520 |
-
$this->isValidAdminArea(
|
|
|
521 |
);
|
522 |
if ( $bShow ) {
|
523 |
$aMenuItems = apply_filters( $this->prefix( 'admin_bar_menu_items' ), [] );
|
@@ -1612,8 +1596,7 @@ class Controller {
|
|
1612 |
public function getPreviousVersion() {
|
1613 |
$oOpts = $this->getPluginControllerOptions();
|
1614 |
if ( empty( $oOpts->previous_version ) ) {
|
1615 |
-
$oOpts->previous_version =
|
1616 |
-
// $oOpts->previous_version = $this->getVersion();
|
1617 |
}
|
1618 |
return $oOpts->previous_version;
|
1619 |
}
|
@@ -1657,14 +1640,6 @@ class Controller {
|
|
1657 |
return self::$oControllerOptions;
|
1658 |
}
|
1659 |
|
1660 |
-
/**
|
1661 |
-
* @deprecated 9.0.4
|
1662 |
-
*/
|
1663 |
-
protected function deletePluginControllerOptions() {
|
1664 |
-
$this->setPluginControllerOptions( false );
|
1665 |
-
$this->saveCurrentPluginControllerOptions();
|
1666 |
-
}
|
1667 |
-
|
1668 |
protected function deleteCronJobs() {
|
1669 |
$oWpCron = Services::WpCron();
|
1670 |
$aCrons = $oWpCron->getCrons();
|
@@ -1734,24 +1709,12 @@ class Controller {
|
|
1734 |
return strtolower( get_class() );
|
1735 |
}
|
1736 |
|
1737 |
-
/**
|
1738 |
-
* @param string $sPathToLib
|
1739 |
-
* @return mixed
|
1740 |
-
*/
|
1741 |
-
public function loadLib( $sPathToLib ) {
|
1742 |
-
return include( $this->getPath_LibFile( $sPathToLib ) );
|
1743 |
-
}
|
1744 |
-
|
1745 |
-
/**
|
1746 |
-
*/
|
1747 |
public function deactivateSelf() {
|
1748 |
if ( $this->isPluginAdmin() && function_exists( 'deactivate_plugins' ) ) {
|
1749 |
deactivate_plugins( $this->getPluginBaseFile() );
|
1750 |
}
|
1751 |
}
|
1752 |
|
1753 |
-
/**
|
1754 |
-
*/
|
1755 |
public function clearSession() {
|
1756 |
Services::Response()->cookieDelete( $this->getPluginPrefix() );
|
1757 |
self::$sSessionId = null;
|
@@ -1763,7 +1726,6 @@ class Controller {
|
|
1763 |
public function deleteForceOffFile() {
|
1764 |
if ( $this->getIfForceOffActive() ) {
|
1765 |
Services::WpFs()->deleteFile( $this->getForceOffFilePath() );
|
1766 |
-
$this->sForceOffFile = null;
|
1767 |
unset( $this->file_forceoff );
|
1768 |
clearstatcache();
|
1769 |
}
|
@@ -1771,23 +1733,22 @@ class Controller {
|
|
1771 |
}
|
1772 |
|
1773 |
/**
|
1774 |
-
*
|
1775 |
*/
|
1776 |
public function getIfForceOffActive() {
|
1777 |
-
return
|
1778 |
}
|
1779 |
|
1780 |
/**
|
1781 |
-
* @return
|
1782 |
*/
|
1783 |
protected function getForceOffFilePath() {
|
1784 |
-
if ( !isset( $this->
|
1785 |
-
$
|
1786 |
-
$
|
1787 |
-
$this->
|
1788 |
-
$this->file_forceoff = $this->sForceOffFile;
|
1789 |
}
|
1790 |
-
return $this->
|
1791 |
}
|
1792 |
|
1793 |
/**
|
@@ -1796,7 +1757,11 @@ class Controller {
|
|
1796 |
*/
|
1797 |
public function getSessionId( $bSetIfNeeded = true ) {
|
1798 |
if ( empty( self::$sSessionId ) ) {
|
1799 |
-
|
|
|
|
|
|
|
|
|
1800 |
if ( empty( self::$sSessionId ) && $bSetIfNeeded ) {
|
1801 |
self::$sSessionId = md5( uniqid( $this->getPluginPrefix() ) );
|
1802 |
$this->setSessionCookie();
|
@@ -1833,11 +1798,9 @@ class Controller {
|
|
1833 |
return !empty( $sSessionId );
|
1834 |
}
|
1835 |
|
1836 |
-
/**
|
1837 |
-
*/
|
1838 |
protected function setSessionCookie() {
|
1839 |
Services::Response()->cookieSet(
|
1840 |
-
|
1841 |
$this->getSessionId(),
|
1842 |
Services::Request()->ts() + DAY_IN_SECONDS*30,
|
1843 |
Services::WpGeneral()->getCookiePath(),
|
15 |
* @property bool $plugin_deactivating
|
16 |
* @property bool $plugin_deleting
|
17 |
* @property bool $plugin_reset
|
18 |
+
* @property false|string $file_forceoff
|
19 |
* @property string $base_file
|
20 |
* @property string $root_file
|
21 |
* @property bool $user_can_base_permissions
|
46 |
*/
|
47 |
protected $bRebuildOptions;
|
48 |
|
|
|
|
|
|
|
|
|
|
|
49 |
/**
|
50 |
* @var string
|
51 |
*/
|
213 |
}
|
214 |
}
|
215 |
|
|
|
|
|
216 |
public function adminNoticeDoesNotMeetRequirements() {
|
217 |
$aMessages = $this->getRequirementsMessages();
|
218 |
if ( !empty( $aMessages ) && is_array( $aMessages ) ) {
|
234 |
}
|
235 |
}
|
236 |
|
|
|
|
|
237 |
public function adminNoticePluginFailedToLoad() {
|
238 |
$aDisplayData = [
|
239 |
'strings' => [
|
323 |
return $bSuccess;
|
324 |
}
|
325 |
|
|
|
|
|
326 |
protected function doRegisterHooks() {
|
327 |
register_deactivation_hook( $this->getRootFile(), [ $this, 'onWpDeactivatePlugin' ] );
|
328 |
|
386 |
);
|
387 |
}
|
388 |
|
|
|
|
|
389 |
public function onWpAdminInit() {
|
390 |
add_action( 'admin_bar_menu', [ $this, 'onWpAdminBarMenu' ], 100 );
|
391 |
add_action( 'wp_dashboard_setup', [ $this, 'onWpDashboardSetup' ] );
|
416 |
return $aHeaders;
|
417 |
}
|
418 |
|
|
|
|
|
419 |
public function onWpInit() {
|
420 |
$this->getMeetsBasePermissions();
|
421 |
add_action( 'wp_enqueue_scripts', [ $this, 'onWpEnqueueFrontendCss' ], 99 );
|
489 |
->run();
|
490 |
}
|
491 |
|
|
|
|
|
492 |
public function onWpAdminMenu() {
|
493 |
if ( $this->isValidAdminArea() ) {
|
494 |
$this->createPluginMenu();
|
500 |
*/
|
501 |
public function onWpAdminBarMenu( $oAdminBar ) {
|
502 |
$bShow = apply_filters( $this->prefix( 'show_admin_bar_menu' ),
|
503 |
+
$this->isValidAdminArea( true )
|
504 |
+
&& (bool)$this->getPluginSpec_Property( 'show_admin_bar_menu' )
|
505 |
);
|
506 |
if ( $bShow ) {
|
507 |
$aMenuItems = apply_filters( $this->prefix( 'admin_bar_menu_items' ), [] );
|
1596 |
public function getPreviousVersion() {
|
1597 |
$oOpts = $this->getPluginControllerOptions();
|
1598 |
if ( empty( $oOpts->previous_version ) ) {
|
1599 |
+
$oOpts->previous_version = $this->getVersion();
|
|
|
1600 |
}
|
1601 |
return $oOpts->previous_version;
|
1602 |
}
|
1640 |
return self::$oControllerOptions;
|
1641 |
}
|
1642 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1643 |
protected function deleteCronJobs() {
|
1644 |
$oWpCron = Services::WpCron();
|
1645 |
$aCrons = $oWpCron->getCrons();
|
1709 |
return strtolower( get_class() );
|
1710 |
}
|
1711 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1712 |
public function deactivateSelf() {
|
1713 |
if ( $this->isPluginAdmin() && function_exists( 'deactivate_plugins' ) ) {
|
1714 |
deactivate_plugins( $this->getPluginBaseFile() );
|
1715 |
}
|
1716 |
}
|
1717 |
|
|
|
|
|
1718 |
public function clearSession() {
|
1719 |
Services::Response()->cookieDelete( $this->getPluginPrefix() );
|
1720 |
self::$sSessionId = null;
|
1726 |
public function deleteForceOffFile() {
|
1727 |
if ( $this->getIfForceOffActive() ) {
|
1728 |
Services::WpFs()->deleteFile( $this->getForceOffFilePath() );
|
|
|
1729 |
unset( $this->file_forceoff );
|
1730 |
clearstatcache();
|
1731 |
}
|
1733 |
}
|
1734 |
|
1735 |
/**
|
1736 |
+
* @return bool
|
1737 |
*/
|
1738 |
public function getIfForceOffActive() {
|
1739 |
+
return $this->getForceOffFilePath() !== false;
|
1740 |
}
|
1741 |
|
1742 |
/**
|
1743 |
+
* @return false|string
|
1744 |
*/
|
1745 |
protected function getForceOffFilePath() {
|
1746 |
+
if ( !isset( $this->file_forceoff ) ) {
|
1747 |
+
$FS = Services::WpFs();
|
1748 |
+
$file = $FS->findFileInDir( 'forceoff', $this->getRootDir(), false, false );
|
1749 |
+
$this->file_forceoff = empty( $file ) ? false : $file;
|
|
|
1750 |
}
|
1751 |
+
return $this->file_forceoff;
|
1752 |
}
|
1753 |
|
1754 |
/**
|
1757 |
*/
|
1758 |
public function getSessionId( $bSetIfNeeded = true ) {
|
1759 |
if ( empty( self::$sSessionId ) ) {
|
1760 |
+
$req = Services::Request();
|
1761 |
+
self::$sSessionId = $req->cookie( 'wp-'.$this->getPluginPrefix(), '' );
|
1762 |
+
if ( empty( self::$sSessionId ) ) { /* the old cookie name */
|
1763 |
+
self::$sSessionId = $req->cookie( $this->getPluginPrefix(), '' );
|
1764 |
+
}
|
1765 |
if ( empty( self::$sSessionId ) && $bSetIfNeeded ) {
|
1766 |
self::$sSessionId = md5( uniqid( $this->getPluginPrefix() ) );
|
1767 |
$this->setSessionCookie();
|
1798 |
return !empty( $sSessionId );
|
1799 |
}
|
1800 |
|
|
|
|
|
1801 |
protected function setSessionCookie() {
|
1802 |
Services::Response()->cookieSet(
|
1803 |
+
'wp-'.$this->getPluginPrefix(),
|
1804 |
$this->getSessionId(),
|
1805 |
Services::Request()->ts() + DAY_IN_SECONDS*30,
|
1806 |
Services::WpGeneral()->getCookiePath(),
|
src/lib/src/Controller/Utilities/Upgrade.php
CHANGED
@@ -13,10 +13,10 @@ class Upgrade {
|
|
13 |
$oCon = $this->getCon();
|
14 |
|
15 |
if ( $oCon->getPreviousVersion() !== $oCon->getVersion() ) {
|
16 |
-
foreach ( $oCon->modules as $
|
17 |
-
$
|
18 |
-
if ( $
|
19 |
-
$
|
20 |
}
|
21 |
}
|
22 |
}
|
13 |
$oCon = $this->getCon();
|
14 |
|
15 |
if ( $oCon->getPreviousVersion() !== $oCon->getVersion() ) {
|
16 |
+
foreach ( $oCon->modules as $mod ) {
|
17 |
+
$H = $mod->getUpgradeHandler();
|
18 |
+
if ( $H instanceof Shield\Modules\Base\Upgrade ) {
|
19 |
+
$H->setMod( $mod )->execute();
|
20 |
}
|
21 |
}
|
22 |
}
|
src/lib/src/Databases/AdminNotes/Handler.php
CHANGED
@@ -10,19 +10,17 @@ class Handler extends Base\Handler {
|
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
return $oOpts->getDbColumns_Notes();
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function getDefaultTableName() {
|
23 |
-
/** @var Options $
|
24 |
-
$
|
25 |
-
return $
|
26 |
}
|
27 |
|
28 |
/**
|
@@ -38,4 +36,12 @@ class Handler extends Base\Handler {
|
|
38 |
PRIMARY KEY (id)
|
39 |
) %s;";
|
40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
+
public function getColumns() {
|
14 |
+
return $this->getOptions()->getDef( 'db_notes_table_columns' );
|
|
|
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string
|
19 |
*/
|
20 |
protected function getDefaultTableName() {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
return $opts->getDbTable_Notes();
|
24 |
}
|
25 |
|
26 |
/**
|
36 |
PRIMARY KEY (id)
|
37 |
) %s;";
|
38 |
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return string[]
|
42 |
+
* @deprecated 9.2.0
|
43 |
+
*/
|
44 |
+
protected function getDefaultColumnsDefinition() {
|
45 |
+
return $this->getOptions()->getDef( 'db_notes_table_columns' );
|
46 |
+
}
|
47 |
}
|
src/lib/src/Databases/AuditTrail/Handler.php
CHANGED
@@ -8,28 +8,26 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail\Options;
|
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
-
/** @var Options $
|
12 |
-
$
|
13 |
-
$this->
|
14 |
-
$this->tableTrimExcess( $
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return array
|
19 |
*/
|
20 |
-
|
21 |
-
|
22 |
-
$oOpts = $this->getOptions();
|
23 |
-
return $oOpts->getDbColumns_AuditTrail();
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
* @return string
|
28 |
*/
|
29 |
protected function getDefaultTableName() {
|
30 |
-
/** @var Options $
|
31 |
-
$
|
32 |
-
return $
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -54,4 +52,12 @@ class Handler extends Base\Handler {
|
|
54 |
PRIMARY KEY (id)
|
55 |
) %s;";
|
56 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
+
/** @var Options $opts */
|
12 |
+
$opts = $this->getOptions();
|
13 |
+
$this->tableCleanExpired( $opts->getAutoCleanDays() );
|
14 |
+
$this->tableTrimExcess( $opts->getMaxEntries() );
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return array
|
19 |
*/
|
20 |
+
public function getColumns() {
|
21 |
+
return $this->getOptions()->getDef( 'audit_trail_table_columns' );
|
|
|
|
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
* @return string
|
26 |
*/
|
27 |
protected function getDefaultTableName() {
|
28 |
+
/** @var Options $opts */
|
29 |
+
$opts = $this->getOptions();
|
30 |
+
return $opts->getDbTable_AuditTrail();
|
31 |
}
|
32 |
|
33 |
/**
|
52 |
PRIMARY KEY (id)
|
53 |
) %s;";
|
54 |
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return string[]
|
58 |
+
* @deprecated 9.2.0
|
59 |
+
*/
|
60 |
+
protected function getDefaultColumnsDefinition() {
|
61 |
+
return $this->getOptions()->getDef( 'audit_trail_table_columns' );
|
62 |
+
}
|
63 |
}
|
src/lib/src/Databases/Base/Handler.php
CHANGED
@@ -30,22 +30,11 @@ class Handler {
|
|
30 |
*/
|
31 |
protected $sTable;
|
32 |
|
33 |
-
/**
|
34 |
-
* @var bool
|
35 |
-
* @deprecated 9.0.4
|
36 |
-
*/
|
37 |
-
private $bTableExist;
|
38 |
-
|
39 |
/**
|
40 |
* @var bool
|
41 |
*/
|
42 |
private $bIsReady;
|
43 |
|
44 |
-
/**
|
45 |
-
* @var string
|
46 |
-
*/
|
47 |
-
private $sSqlCreate;
|
48 |
-
|
49 |
public function __construct() {
|
50 |
}
|
51 |
|
@@ -54,9 +43,9 @@ class Handler {
|
|
54 |
|
55 |
/**
|
56 |
* @param int $nAutoExpireDays
|
57 |
-
* @return $this
|
58 |
*/
|
59 |
-
public function
|
60 |
$nAutoExpire = $nAutoExpireDays*DAY_IN_SECONDS;
|
61 |
if ( $nAutoExpire > 0 ) {
|
62 |
$this->deleteRowsOlderThan( Services::Request()->ts() - $nAutoExpire );
|
@@ -84,11 +73,26 @@ class Handler {
|
|
84 |
return is_array( $this->aColActual ) ? $this->aColActual : [];
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/**
|
88 |
* @return string[]
|
89 |
*/
|
90 |
public function getColumnsDefinition() {
|
91 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
|
94 |
/**
|
@@ -158,7 +162,7 @@ class Handler {
|
|
158 |
* @return string
|
159 |
*/
|
160 |
public function getSqlCreate() {
|
161 |
-
return
|
162 |
}
|
163 |
|
164 |
/**
|
@@ -180,7 +184,7 @@ class Handler {
|
|
180 |
}
|
181 |
$oDB = Services::WpDb();
|
182 |
$sSql = sprintf( $sSql, $this->getTable(), $oDB->getCharCollate() );
|
183 |
-
$this->
|
184 |
return $this;
|
185 |
}
|
186 |
|
@@ -191,7 +195,7 @@ class Handler {
|
|
191 |
public function tableDelete( $bTruncate = false ) {
|
192 |
$table = $this->getTable();
|
193 |
$oDB = Services::WpDb();
|
194 |
-
$mResult = !$this->
|
195 |
( $bTruncate ? $oDB->doTruncateTable( $table ) : $oDB->doDropTable( $table ) );
|
196 |
$this->reset();
|
197 |
return $mResult !== false;
|
@@ -214,7 +218,7 @@ class Handler {
|
|
214 |
$this->tableCreate();
|
215 |
|
216 |
if ( !$this->isReady( true ) ) {
|
217 |
-
$this->
|
218 |
$this->tableCreate();
|
219 |
}
|
220 |
}
|
@@ -246,7 +250,7 @@ class Handler {
|
|
246 |
|
247 |
if ( !isset( $this->bIsReady ) ) {
|
248 |
try {
|
249 |
-
$this->bIsReady = $this->
|
250 |
}
|
251 |
catch ( \Exception $e ) {
|
252 |
$this->bIsReady = false;
|
@@ -265,15 +269,6 @@ class Handler {
|
|
265 |
return $this;
|
266 |
}
|
267 |
|
268 |
-
/**
|
269 |
-
* @param string $sSqlCreate
|
270 |
-
* @return $this
|
271 |
-
*/
|
272 |
-
public function setSqlCreate( $sSqlCreate ) {
|
273 |
-
$this->sSqlCreate = $sSqlCreate;
|
274 |
-
return $this;
|
275 |
-
}
|
276 |
-
|
277 |
/**
|
278 |
* @param string $sTable
|
279 |
* @return $this
|
@@ -286,7 +281,7 @@ class Handler {
|
|
286 |
/**
|
287 |
* @return string[]
|
288 |
*/
|
289 |
-
|
290 |
return [];
|
291 |
}
|
292 |
|
@@ -335,7 +330,7 @@ class Handler {
|
|
335 |
* @throws \Exception
|
336 |
*/
|
337 |
protected function verifyTableStructure() {
|
338 |
-
$aColDef = array_map( 'strtolower', $this->
|
339 |
if ( empty( $aColDef ) ) {
|
340 |
throw new \Exception( 'Could not verify table structure as no columns definition provided' );
|
341 |
}
|
@@ -367,28 +362,6 @@ class Handler {
|
|
367 |
return $this;
|
368 |
}
|
369 |
|
370 |
-
/**
|
371 |
-
* @return bool
|
372 |
-
* @deprecated 9.0.4
|
373 |
-
*/
|
374 |
-
public function isTable() {
|
375 |
-
return Services::WpDb()->getIfTableExists( $this->getTable() );
|
376 |
-
}
|
377 |
-
|
378 |
-
/**
|
379 |
-
* @param bool $bTruncate
|
380 |
-
* @return bool
|
381 |
-
* @deprecated 9.0.4
|
382 |
-
*/
|
383 |
-
public function deleteTable( $bTruncate = false ) {
|
384 |
-
$table = $this->getTable();
|
385 |
-
$oDB = Services::WpDb();
|
386 |
-
$mResult = !$this->isTable() ||
|
387 |
-
( $bTruncate ? $oDB->doTruncateTable( $table ) : $oDB->doDropTable( $table ) );
|
388 |
-
$this->reset();
|
389 |
-
return $mResult !== false;
|
390 |
-
}
|
391 |
-
|
392 |
/**
|
393 |
* @return string[]
|
394 |
*/
|
@@ -414,4 +387,30 @@ class Handler {
|
|
414 |
protected function getPrimaryKeySpec() {
|
415 |
return 'PRIMARY KEY (id)';
|
416 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
}
|
30 |
*/
|
31 |
protected $sTable;
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
/**
|
34 |
* @var bool
|
35 |
*/
|
36 |
private $bIsReady;
|
37 |
|
|
|
|
|
|
|
|
|
|
|
38 |
public function __construct() {
|
39 |
}
|
40 |
|
43 |
|
44 |
/**
|
45 |
* @param int $nAutoExpireDays
|
46 |
+
* @return $this
|
47 |
*/
|
48 |
+
public function tableCleanExpired( $nAutoExpireDays ) {
|
49 |
$nAutoExpire = $nAutoExpireDays*DAY_IN_SECONDS;
|
50 |
if ( $nAutoExpire > 0 ) {
|
51 |
$this->deleteRowsOlderThan( Services::Request()->ts() - $nAutoExpire );
|
73 |
return is_array( $this->aColActual ) ? $this->aColActual : [];
|
74 |
}
|
75 |
|
76 |
+
/**
|
77 |
+
* @return string[]
|
78 |
+
* @deprecated 9.2.0
|
79 |
+
*/
|
80 |
+
protected function getDefaultColumnsDefinition() {
|
81 |
+
return $this->getColumns();
|
82 |
+
}
|
83 |
+
|
84 |
/**
|
85 |
* @return string[]
|
86 |
*/
|
87 |
public function getColumnsDefinition() {
|
88 |
+
return $this->enumerateColumns();
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @return string[]
|
93 |
+
*/
|
94 |
+
public function getColumnas() {
|
95 |
+
return $this->getColumns();
|
96 |
}
|
97 |
|
98 |
/**
|
162 |
* @return string
|
163 |
*/
|
164 |
public function getSqlCreate() {
|
165 |
+
return $this->getDefaultCreateTableSql();
|
166 |
}
|
167 |
|
168 |
/**
|
184 |
}
|
185 |
$oDB = Services::WpDb();
|
186 |
$sSql = sprintf( $sSql, $this->getTable(), $oDB->getCharCollate() );
|
187 |
+
$this->tableExists() ? $oDB->dbDelta( $sSql ) : $oDB->doSql( $sSql );
|
188 |
return $this;
|
189 |
}
|
190 |
|
195 |
public function tableDelete( $bTruncate = false ) {
|
196 |
$table = $this->getTable();
|
197 |
$oDB = Services::WpDb();
|
198 |
+
$mResult = !$this->tableExists() ||
|
199 |
( $bTruncate ? $oDB->doTruncateTable( $table ) : $oDB->doDropTable( $table ) );
|
200 |
$this->reset();
|
201 |
return $mResult !== false;
|
218 |
$this->tableCreate();
|
219 |
|
220 |
if ( !$this->isReady( true ) ) {
|
221 |
+
$this->tableDelete();
|
222 |
$this->tableCreate();
|
223 |
}
|
224 |
}
|
250 |
|
251 |
if ( !isset( $this->bIsReady ) ) {
|
252 |
try {
|
253 |
+
$this->bIsReady = $this->tableExists() && $this->verifyTableStructure();
|
254 |
}
|
255 |
catch ( \Exception $e ) {
|
256 |
$this->bIsReady = false;
|
269 |
return $this;
|
270 |
}
|
271 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
/**
|
273 |
* @param string $sTable
|
274 |
* @return $this
|
281 |
/**
|
282 |
* @return string[]
|
283 |
*/
|
284 |
+
public function getColumns() {
|
285 |
return [];
|
286 |
}
|
287 |
|
330 |
* @throws \Exception
|
331 |
*/
|
332 |
protected function verifyTableStructure() {
|
333 |
+
$aColDef = array_map( 'strtolower', $this->getColumns() );
|
334 |
if ( empty( $aColDef ) ) {
|
335 |
throw new \Exception( 'Could not verify table structure as no columns definition provided' );
|
336 |
}
|
362 |
return $this;
|
363 |
}
|
364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
/**
|
366 |
* @return string[]
|
367 |
*/
|
387 |
protected function getPrimaryKeySpec() {
|
388 |
return 'PRIMARY KEY (id)';
|
389 |
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* @param bool $bTruncate
|
393 |
+
* @return bool
|
394 |
+
* @deprecated 9.0.4
|
395 |
+
*/
|
396 |
+
public function deleteTable( $bTruncate = false ) {
|
397 |
+
return $this->tableDelete( $bTruncate );
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* @return bool
|
402 |
+
* @deprecated 9.0.4
|
403 |
+
*/
|
404 |
+
public function isTable() {
|
405 |
+
return $this->tableExists();
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* @param int $nAutoExpireDays
|
410 |
+
* @return $this
|
411 |
+
* @deprecated 9.2.0
|
412 |
+
*/
|
413 |
+
public function cleanDb( $nAutoExpireDays ) {
|
414 |
+
return $this->tableCleanExpired( $nAutoExpireDays );
|
415 |
+
}
|
416 |
}
|
src/lib/src/Databases/ChangeTracking/Handler.php
CHANGED
@@ -10,19 +10,17 @@ class Handler extends Base\Handler {
|
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
return $oOpts->getDbColumns_ChangeTracking();
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function getDefaultTableName() {
|
23 |
-
/** @var Options $
|
24 |
-
$
|
25 |
-
return $
|
26 |
}
|
27 |
|
28 |
/**
|
@@ -38,4 +36,12 @@ class Handler extends Base\Handler {
|
|
38 |
PRIMARY KEY (id)
|
39 |
) %s;";
|
40 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
+
public function getColumns() {
|
14 |
+
return $this->getOptions()->getDef( 'table_columns_changetracking' );
|
|
|
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string
|
19 |
*/
|
20 |
protected function getDefaultTableName() {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
return $opts->getDbTable_ChangeTracking();
|
24 |
}
|
25 |
|
26 |
/**
|
36 |
PRIMARY KEY (id)
|
37 |
) %s;";
|
38 |
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return string[]
|
42 |
+
* @deprecated 9.2.0
|
43 |
+
*/
|
44 |
+
protected function getDefaultColumnsDefinition() {
|
45 |
+
return $this->getOptions()->getDef( 'table_columns_changetracking' );
|
46 |
+
}
|
47 |
}
|
src/lib/src/Databases/Events/Handler.php
CHANGED
@@ -33,27 +33,25 @@ class Handler extends Base\Handler {
|
|
33 |
$oEvt->event = $sEvent;
|
34 |
$oEvt->count = max( 1, (int)$nCount );
|
35 |
$oEvt->created_at = max( 1, $nTs );
|
36 |
-
/** @var Insert $
|
37 |
-
$
|
38 |
-
return $
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
* @return string[]
|
43 |
*/
|
44 |
-
|
45 |
-
|
46 |
-
$oOpts = $this->getOptions();
|
47 |
-
return $oOpts->getDbColumns_Events();
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
* @return string
|
52 |
*/
|
53 |
protected function getDefaultTableName() {
|
54 |
-
/** @var Options $
|
55 |
-
$
|
56 |
-
return $
|
57 |
}
|
58 |
|
59 |
/**
|
@@ -69,4 +67,12 @@ class Handler extends Base\Handler {
|
|
69 |
PRIMARY KEY (id)
|
70 |
) %s;";
|
71 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
33 |
$oEvt->event = $sEvent;
|
34 |
$oEvt->count = max( 1, (int)$nCount );
|
35 |
$oEvt->created_at = max( 1, $nTs );
|
36 |
+
/** @var Insert $QI */
|
37 |
+
$QI = $this->getQueryInserter();
|
38 |
+
return $QI->insert( $oEvt );
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
* @return string[]
|
43 |
*/
|
44 |
+
public function getColumns() {
|
45 |
+
return $this->getOptions()->getDef( 'events_table_columns' );
|
|
|
|
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
* @return string
|
50 |
*/
|
51 |
protected function getDefaultTableName() {
|
52 |
+
/** @var Options $opts */
|
53 |
+
$opts = $this->getOptions();
|
54 |
+
return $opts->getDbTable_Events();
|
55 |
}
|
56 |
|
57 |
/**
|
67 |
PRIMARY KEY (id)
|
68 |
) %s;";
|
69 |
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @return string[]
|
73 |
+
* @deprecated 9.2.0
|
74 |
+
*/
|
75 |
+
protected function getDefaultColumnsDefinition() {
|
76 |
+
return $this->getOptions()->getDef( 'events_table_columns' );
|
77 |
+
}
|
78 |
}
|
src/lib/src/Databases/FileLocker/Handler.php
CHANGED
@@ -10,19 +10,17 @@ class Handler extends Base\Handler {
|
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
return $oOpts->getDbColumns_FileLocker();
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function getDefaultTableName() {
|
23 |
-
/** @var Options $
|
24 |
-
$
|
25 |
-
return $
|
26 |
}
|
27 |
|
28 |
/**
|
@@ -45,4 +43,12 @@ class Handler extends Base\Handler {
|
|
45 |
PRIMARY KEY (id)
|
46 |
) %s;";
|
47 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
}
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
+
public function getColumns() {
|
14 |
+
return $this->getOptions()->getDef( 'table_columns_filelocker' );
|
|
|
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string
|
19 |
*/
|
20 |
protected function getDefaultTableName() {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
return $opts->getDbTable_FileLocker();
|
24 |
}
|
25 |
|
26 |
/**
|
43 |
PRIMARY KEY (id)
|
44 |
) %s;";
|
45 |
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @return string[]
|
49 |
+
* @deprecated 9.2.0
|
50 |
+
*/
|
51 |
+
protected function getDefaultColumnsDefinition() {
|
52 |
+
return $this->getOptions()->getDef( 'table_columns_filelocker' );
|
53 |
+
}
|
54 |
}
|
src/lib/src/Databases/GeoIp/Handler.php
CHANGED
@@ -8,27 +8,23 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Options;
|
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
-
|
12 |
-
$oOpts = $this->getOptions();
|
13 |
-
$this->cleanDb( $oOpts->getDef( 'db_autoexpire_geoip' ) );
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
* @return string[]
|
18 |
*/
|
19 |
-
|
20 |
-
|
21 |
-
$oOpts = $this->getOptions();
|
22 |
-
return $oOpts->getDbColumns_GeoIp();
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
* @return string
|
27 |
*/
|
28 |
protected function getDefaultTableName() {
|
29 |
-
/** @var Options $
|
30 |
-
$
|
31 |
-
return $
|
32 |
}
|
33 |
|
34 |
/**
|
@@ -44,4 +40,12 @@ class Handler extends Base\Handler {
|
|
44 |
PRIMARY KEY (id)
|
45 |
) %s;";
|
46 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
}
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
+
$this->tableCleanExpired( $this->getOptions()->getDef( 'db_autoexpire_geoip' ) );
|
|
|
|
|
12 |
}
|
13 |
|
14 |
/**
|
15 |
* @return string[]
|
16 |
*/
|
17 |
+
public function getColumns() {
|
18 |
+
return $this->getOptions()->getDef( 'geoip_table_columns' );
|
|
|
|
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
* @return string
|
23 |
*/
|
24 |
protected function getDefaultTableName() {
|
25 |
+
/** @var Options $opts */
|
26 |
+
$opts = $this->getOptions();
|
27 |
+
return $opts->getDbTable_GeoIp();
|
28 |
}
|
29 |
|
30 |
/**
|
40 |
PRIMARY KEY (id)
|
41 |
) %s;";
|
42 |
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return string[]
|
46 |
+
* @deprecated 9.2.0
|
47 |
+
*/
|
48 |
+
protected function getDefaultColumnsDefinition() {
|
49 |
+
return $this->getOptions()->getDef( 'geoip_table_columns' );
|
50 |
+
}
|
51 |
}
|
src/lib/src/Databases/IPs/Handler.php
CHANGED
@@ -9,14 +9,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
9 |
class Handler extends Base\Handler {
|
10 |
|
11 |
public function autoCleanDb() {
|
12 |
-
/** @var
|
13 |
-
$
|
14 |
-
/** @var
|
15 |
-
$
|
16 |
-
|
17 |
-
|
18 |
-
$oDel->filterByBlacklist()
|
19 |
-
->filterByLastAccessBefore( Services::Request()->ts() - $oOpts->getAutoExpireTime() )
|
20 |
->query();
|
21 |
}
|
22 |
|
@@ -34,34 +32,31 @@ class Handler extends Base\Handler {
|
|
34 |
/**
|
35 |
* @return string[]
|
36 |
*/
|
37 |
-
|
38 |
-
|
39 |
-
$oOpts = $this->getOptions();
|
40 |
-
return $oOpts->getDbColumns_IPs();
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
* @return string
|
45 |
*/
|
46 |
protected function getDefaultTableName() {
|
47 |
-
/** @var Options $
|
48 |
-
$
|
49 |
-
return $
|
50 |
}
|
51 |
|
52 |
/**
|
53 |
* @return string[]
|
54 |
*/
|
55 |
protected function getColumnsAsArray() {
|
56 |
-
return
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
];
|
66 |
}
|
67 |
}
|
9 |
class Handler extends Base\Handler {
|
10 |
|
11 |
public function autoCleanDb() {
|
12 |
+
/** @var Options $opts */
|
13 |
+
$opts = $this->getOptions();
|
14 |
+
/** @var Delete $del */
|
15 |
+
$del = $this->getQueryDeleter();
|
16 |
+
$del->filterByBlacklist()
|
17 |
+
->filterByLastAccessBefore( Services::Request()->ts() - $opts->getAutoExpireTime() )
|
|
|
|
|
18 |
->query();
|
19 |
}
|
20 |
|
32 |
/**
|
33 |
* @return string[]
|
34 |
*/
|
35 |
+
public function getColumns() {
|
36 |
+
return array_keys( $this->getColumnsDefinition() );
|
|
|
|
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
* @return string
|
41 |
*/
|
42 |
protected function getDefaultTableName() {
|
43 |
+
/** @var Options $opts */
|
44 |
+
$opts = $this->getOptions();
|
45 |
+
return $opts->getDbTable_IPs();
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
* @return string[]
|
50 |
*/
|
51 |
protected function getColumnsAsArray() {
|
52 |
+
return $this->getOptions()->getDef( 'ip_list_table_columns' );
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return string[]
|
57 |
+
* @deprecated 9.2.0
|
58 |
+
*/
|
59 |
+
protected function getDefaultColumnsDefinition() {
|
60 |
+
return $this->getOptions()->getDef( 'ip_list_table_columns' );
|
|
|
61 |
}
|
62 |
}
|
src/lib/src/Databases/Reports/Handler.php
CHANGED
@@ -11,25 +11,23 @@ class Handler extends Base\Handler {
|
|
11 |
const TYPE_INFO = 'nfo';
|
12 |
|
13 |
public function autoCleanDb() {
|
14 |
-
$this->
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
19 |
*/
|
20 |
-
|
21 |
-
|
22 |
-
$oOpts = $this->getOptions();
|
23 |
-
return $oOpts->getDbColumns_Reports();
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
* @return string
|
28 |
*/
|
29 |
protected function getDefaultTableName() {
|
30 |
-
/** @var Options $
|
31 |
-
$
|
32 |
-
return $
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -48,4 +46,12 @@ class Handler extends Base\Handler {
|
|
48 |
PRIMARY KEY (id)
|
49 |
) %s;";
|
50 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
11 |
const TYPE_INFO = 'nfo';
|
12 |
|
13 |
public function autoCleanDb() {
|
14 |
+
$this->tableCleanExpired( 30 );
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
19 |
*/
|
20 |
+
public function getColumns() {
|
21 |
+
return $this->getOptions()->getDef( 'reports_table_columns' );
|
|
|
|
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
* @return string
|
26 |
*/
|
27 |
protected function getDefaultTableName() {
|
28 |
+
/** @var Options $opts */
|
29 |
+
$opts = $this->getOptions();
|
30 |
+
return $opts->getDbTable_Reports();
|
31 |
}
|
32 |
|
33 |
/**
|
46 |
PRIMARY KEY (id)
|
47 |
) %s;";
|
48 |
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @return string[]
|
52 |
+
* @deprecated 9.2.0
|
53 |
+
*/
|
54 |
+
protected function getDefaultColumnsDefinition() {
|
55 |
+
return $this->getOptions()->getDef( 'reports_table_columns' );
|
56 |
+
}
|
57 |
}
|
src/lib/src/Databases/ScanQueue/Handler.php
CHANGED
@@ -10,19 +10,17 @@ class Handler extends Base\Handler {
|
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
return $oOpts->getDbColumns_ScanQueue();
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function getDefaultTableName() {
|
23 |
-
/** @var Options $
|
24 |
-
$
|
25 |
-
return $
|
26 |
}
|
27 |
|
28 |
/**
|
@@ -42,4 +40,12 @@ class Handler extends Base\Handler {
|
|
42 |
PRIMARY KEY (id)
|
43 |
) %s;";
|
44 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
+
public function getColumns() {
|
14 |
+
return $this->getOptions()->getDef( 'table_columns_scanqueue' );
|
|
|
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string
|
19 |
*/
|
20 |
protected function getDefaultTableName() {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
return $opts->getDbTable_ScanQueue();
|
24 |
}
|
25 |
|
26 |
/**
|
40 |
PRIMARY KEY (id)
|
41 |
) %s;";
|
42 |
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return string[]
|
46 |
+
* @deprecated 9.2.0
|
47 |
+
*/
|
48 |
+
protected function getDefaultColumnsDefinition() {
|
49 |
+
return $this->getOptions()->getDef( 'table_columns_scanqueue' );
|
50 |
+
}
|
51 |
}
|
src/lib/src/Databases/Scanner/Handler.php
CHANGED
@@ -10,19 +10,17 @@ class Handler extends Base\Handler {
|
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
return $oOpts->getDbColumns_Scanner();
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function getDefaultTableName() {
|
23 |
-
/** @var Options $
|
24 |
-
$
|
25 |
-
return $
|
26 |
}
|
27 |
|
28 |
/**
|
@@ -42,4 +40,12 @@ class Handler extends Base\Handler {
|
|
42 |
PRIMARY KEY (id)
|
43 |
) %s;";
|
44 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
+
public function getColumns() {
|
14 |
+
return $this->getOptions()->getDef( 'table_columns_scanner' );
|
|
|
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string
|
19 |
*/
|
20 |
protected function getDefaultTableName() {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
return $opts->getDbTable_Scanner();
|
24 |
}
|
25 |
|
26 |
/**
|
40 |
PRIMARY KEY (id)
|
41 |
) %s;";
|
42 |
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return string[]
|
46 |
+
* @deprecated 9.2.0
|
47 |
+
*/
|
48 |
+
protected function getDefaultColumnsDefinition() {
|
49 |
+
return $this->getOptions()->getDef( 'table_columns_scanner' );
|
50 |
+
}
|
51 |
}
|
src/lib/src/Databases/Session/Handler.php
CHANGED
@@ -8,25 +8,23 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Sessions\Options;
|
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
-
$this->
|
12 |
}
|
13 |
|
14 |
/**
|
15 |
* @return string[]
|
16 |
*/
|
17 |
-
|
18 |
-
|
19 |
-
$oOpts = $this->getOptions();
|
20 |
-
return $oOpts->getDbColumns_Sessions();
|
21 |
}
|
22 |
|
23 |
/**
|
24 |
* @return string
|
25 |
*/
|
26 |
protected function getDefaultTableName() {
|
27 |
-
/** @var Options $
|
28 |
-
$
|
29 |
-
return $
|
30 |
}
|
31 |
|
32 |
/**
|
@@ -50,4 +48,12 @@ class Handler extends Base\Handler {
|
|
50 |
PRIMARY KEY (id)
|
51 |
) %s;";
|
52 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
}
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
+
$this->tableCleanExpired( 30 );
|
12 |
}
|
13 |
|
14 |
/**
|
15 |
* @return string[]
|
16 |
*/
|
17 |
+
public function getColumns() {
|
18 |
+
return $this->getOptions()->getDef( 'sessions_table_columns' );
|
|
|
|
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
* @return string
|
23 |
*/
|
24 |
protected function getDefaultTableName() {
|
25 |
+
/** @var Options $opts */
|
26 |
+
$opts = $this->getOptions();
|
27 |
+
return $opts->getDbTable_Sessions();
|
28 |
}
|
29 |
|
30 |
/**
|
48 |
PRIMARY KEY (id)
|
49 |
) %s;";
|
50 |
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @return string[]
|
54 |
+
* @deprecated 9.2.0
|
55 |
+
*/
|
56 |
+
protected function getDefaultColumnsDefinition() {
|
57 |
+
return $this->getOptions()->getDef( 'sessions_table_columns' );
|
58 |
+
}
|
59 |
}
|
src/lib/src/Databases/Tally/Handler.php
CHANGED
@@ -10,19 +10,17 @@ class Handler extends Base\Handler {
|
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
$oOpts = $this->getOptions();
|
16 |
-
return $oOpts->getDbColumns_Tallys();
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function getDefaultTableName() {
|
23 |
-
/** @var Options $
|
24 |
-
$
|
25 |
-
return $
|
26 |
}
|
27 |
|
28 |
/**
|
@@ -40,4 +38,12 @@ class Handler extends Base\Handler {
|
|
40 |
PRIMARY KEY (id)
|
41 |
) %s;";
|
42 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
10 |
/**
|
11 |
* @return string[]
|
12 |
*/
|
13 |
+
public function getColumns() {
|
14 |
+
return $this->getOptions()->getDef( 'statistics_table_columns' );
|
|
|
|
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string
|
19 |
*/
|
20 |
protected function getDefaultTableName() {
|
21 |
+
/** @var Options $opts */
|
22 |
+
$opts = $this->getOptions();
|
23 |
+
return $opts->getDbTable_Tallys();
|
24 |
}
|
25 |
|
26 |
/**
|
38 |
PRIMARY KEY (id)
|
39 |
) %s;";
|
40 |
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return string[]
|
44 |
+
* @deprecated 9.2.0
|
45 |
+
*/
|
46 |
+
protected function getDefaultColumnsDefinition() {
|
47 |
+
return $this->getOptions()->getDef( 'statistics_table_columns' );
|
48 |
+
}
|
49 |
}
|
src/lib/src/Databases/Traffic/Handler.php
CHANGED
@@ -8,28 +8,26 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Traffic\Options;
|
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
-
/** @var Options $
|
12 |
-
$
|
13 |
-
$this->
|
14 |
-
$this->tableTrimExcess( $
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
19 |
*/
|
20 |
-
|
21 |
-
|
22 |
-
$oOpts = $this->getOptions();
|
23 |
-
return $oOpts->getDbColumns_TrafficLog();
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
* @return string
|
28 |
*/
|
29 |
protected function getDefaultTableName() {
|
30 |
-
/** @var Options $
|
31 |
-
$
|
32 |
-
return $
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -51,4 +49,12 @@ class Handler extends Base\Handler {
|
|
51 |
PRIMARY KEY (id)
|
52 |
) %s;";
|
53 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
8 |
class Handler extends Base\Handler {
|
9 |
|
10 |
public function autoCleanDb() {
|
11 |
+
/** @var Options $opts */
|
12 |
+
$opts = $this->getOptions();
|
13 |
+
$this->tableCleanExpired( $opts->getAutoCleanDays() );
|
14 |
+
$this->tableTrimExcess( $opts->getMaxEntries() );
|
15 |
}
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
19 |
*/
|
20 |
+
public function getColumns() {
|
21 |
+
return $this->getOptions()->getDef( 'traffic_table_columns' );
|
|
|
|
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
* @return string
|
26 |
*/
|
27 |
protected function getDefaultTableName() {
|
28 |
+
/** @var Options $opts */
|
29 |
+
$opts = $this->getOptions();
|
30 |
+
return $opts->getDbTable_TrafficLog();
|
31 |
}
|
32 |
|
33 |
/**
|
49 |
PRIMARY KEY (id)
|
50 |
) %s;";
|
51 |
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @return string[]
|
55 |
+
* @deprecated 9.2.0
|
56 |
+
*/
|
57 |
+
protected function getDefaultColumnsDefinition() {
|
58 |
+
return $this->getOptions()->getDef( 'traffic_table_columns' );
|
59 |
+
}
|
60 |
}
|
src/lib/src/Helpers/QuickAccess.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Helpers;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Controller\Controller;
|
6 |
+
|
7 |
+
class QuickAccess {
|
8 |
+
|
9 |
+
public static function IsRequestWhiteListed() {
|
10 |
+
try {
|
11 |
+
return Controller::GetInstance()
|
12 |
+
->getModule_IPs()
|
13 |
+
->isVisitorWhitelisted();
|
14 |
+
}
|
15 |
+
catch ( \Exception $e ) {
|
16 |
+
return false;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
}
|
src/lib/src/Modules/AuditTrail/AjaxHandler.php
CHANGED
@@ -8,12 +8,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
-
* @param string $
|
12 |
* @return array
|
13 |
*/
|
14 |
-
protected function processAjaxAction( $
|
15 |
|
16 |
-
switch ( $
|
17 |
case 'render_table_audittrail':
|
18 |
$aResponse = $this->ajaxExec_BuildTableAuditTrail();
|
19 |
break;
|
@@ -23,7 +23,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
23 |
break;
|
24 |
|
25 |
default:
|
26 |
-
$aResponse = parent::processAjaxAction( $
|
27 |
}
|
28 |
|
29 |
return $aResponse;
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
+
* @param string $action
|
12 |
* @return array
|
13 |
*/
|
14 |
+
protected function processAjaxAction( $action ) {
|
15 |
|
16 |
+
switch ( $action ) {
|
17 |
case 'render_table_audittrail':
|
18 |
$aResponse = $this->ajaxExec_BuildTableAuditTrail();
|
19 |
break;
|
23 |
break;
|
24 |
|
25 |
default:
|
26 |
+
$aResponse = parent::processAjaxAction( $action );
|
27 |
}
|
28 |
|
29 |
return $aResponse;
|
src/lib/src/Modules/AuditTrail/Options.php
CHANGED
@@ -9,6 +9,7 @@ class Options extends Base\ShieldOptions {
|
|
9 |
|
10 |
/**
|
11 |
* @return array
|
|
|
12 |
*/
|
13 |
public function getDbColumns_AuditTrail() {
|
14 |
return $this->getDef( 'audit_trail_table_columns' );
|
@@ -16,6 +17,7 @@ class Options extends Base\ShieldOptions {
|
|
16 |
|
17 |
/**
|
18 |
* @return array
|
|
|
19 |
*/
|
20 |
public function getDbColumns_ChangeTracking() {
|
21 |
return $this->getDef( 'table_columns_changetracking' );
|
9 |
|
10 |
/**
|
11 |
* @return array
|
12 |
+
* @deprecated 9.2.0
|
13 |
*/
|
14 |
public function getDbColumns_AuditTrail() {
|
15 |
return $this->getDef( 'audit_trail_table_columns' );
|
17 |
|
18 |
/**
|
19 |
* @return array
|
20 |
+
* @deprecated 9.2.0
|
21 |
*/
|
22 |
public function getDbColumns_ChangeTracking() {
|
23 |
return $this->getDef( 'table_columns_changetracking' );
|
src/lib/src/Modules/AuditTrail/Strings.php
CHANGED
@@ -105,13 +105,13 @@ class Strings extends Base\Strings {
|
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
* @param string $
|
109 |
* @return array
|
110 |
* @throws \Exception
|
111 |
*/
|
112 |
-
public function getSectionStrings( $
|
113 |
|
114 |
-
switch ( $
|
115 |
|
116 |
case 'section_enable_plugin_feature_audit_trail' :
|
117 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -159,7 +159,7 @@ class Strings extends Base\Strings {
|
|
159 |
*/
|
160 |
|
161 |
default:
|
162 |
-
return parent::getSectionStrings( $
|
163 |
}
|
164 |
|
165 |
return [
|
@@ -170,19 +170,17 @@ class Strings extends Base\Strings {
|
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
-
* @param string $
|
174 |
* @return array
|
175 |
* @throws \Exception
|
176 |
*/
|
177 |
-
public function getOptionStrings( $
|
178 |
-
|
179 |
-
|
180 |
-
$
|
181 |
-
|
182 |
-
$oOpts = $oMod->getOptions();
|
183 |
-
$sModName = $oMod->getMainFeatureName();
|
184 |
|
185 |
-
switch ( $
|
186 |
|
187 |
case 'enable_audit_trail' :
|
188 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -196,9 +194,9 @@ class Strings extends Base\Strings {
|
|
196 |
$sDescription = [
|
197 |
__( 'Automatically remove any audit trail entries when this limit is exceeded.', 'wp-simple-firewall' ),
|
198 |
];
|
199 |
-
if ( !$
|
200 |
$sDescription[] = sprintf( __( 'Upgrade to PRO to increase limit above %s.', 'wp-simple-firewall' ),
|
201 |
-
'<code>'.$
|
202 |
}
|
203 |
|
204 |
break;
|
@@ -246,9 +244,9 @@ class Strings extends Base\Strings {
|
|
246 |
break;
|
247 |
|
248 |
case 'enable_audit_context_wpsf' :
|
249 |
-
$sName = $
|
250 |
-
$sSummary = sprintf( __( 'Enable Audit Context - %s', 'wp-simple-firewall' ), $
|
251 |
-
$sDescription = sprintf( __( 'When this context is enabled, the audit trail will track activity relating to: %s', 'wp-simple-firewall' ), $
|
252 |
break;
|
253 |
|
254 |
case 'enable_change_tracking' :
|
@@ -273,7 +271,7 @@ class Strings extends Base\Strings {
|
|
273 |
break;
|
274 |
|
275 |
default:
|
276 |
-
return parent::getOptionStrings( $
|
277 |
}
|
278 |
|
279 |
return [
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* @param string $section
|
109 |
* @return array
|
110 |
* @throws \Exception
|
111 |
*/
|
112 |
+
public function getSectionStrings( $section ) {
|
113 |
|
114 |
+
switch ( $section ) {
|
115 |
|
116 |
case 'section_enable_plugin_feature_audit_trail' :
|
117 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
159 |
*/
|
160 |
|
161 |
default:
|
162 |
+
return parent::getSectionStrings( $section );
|
163 |
}
|
164 |
|
165 |
return [
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
+
* @param string $key
|
174 |
* @return array
|
175 |
* @throws \Exception
|
176 |
*/
|
177 |
+
public function getOptionStrings( $key ) {
|
178 |
+
$con = $this->getCon();
|
179 |
+
/** @var Options $opts */
|
180 |
+
$opts = $this->getOptions();
|
181 |
+
$sModName = $this->getMod()->getMainFeatureName();
|
|
|
|
|
182 |
|
183 |
+
switch ( $key ) {
|
184 |
|
185 |
case 'enable_audit_trail' :
|
186 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
194 |
$sDescription = [
|
195 |
__( 'Automatically remove any audit trail entries when this limit is exceeded.', 'wp-simple-firewall' ),
|
196 |
];
|
197 |
+
if ( !$con->isPremiumActive() ) {
|
198 |
$sDescription[] = sprintf( __( 'Upgrade to PRO to increase limit above %s.', 'wp-simple-firewall' ),
|
199 |
+
'<code>'.$opts->getDef( 'audit_trail_free_max_entries' ).'</code>' );
|
200 |
}
|
201 |
|
202 |
break;
|
244 |
break;
|
245 |
|
246 |
case 'enable_audit_context_wpsf' :
|
247 |
+
$sName = $con->getHumanName();
|
248 |
+
$sSummary = sprintf( __( 'Enable Audit Context - %s', 'wp-simple-firewall' ), $con->getHumanName() );
|
249 |
+
$sDescription = sprintf( __( 'When this context is enabled, the audit trail will track activity relating to: %s', 'wp-simple-firewall' ), $con->getHumanName() );
|
250 |
break;
|
251 |
|
252 |
case 'enable_change_tracking' :
|
271 |
break;
|
272 |
|
273 |
default:
|
274 |
+
return parent::getOptionStrings( $key );
|
275 |
}
|
276 |
|
277 |
return [
|
src/lib/src/Modules/AuditTrail/UI.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
|
7 |
+
class UI extends Base\ShieldUI {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getInsightsConfigCardData() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_AuditTrail $mod */
|
14 |
+
$mod = $this->getMod();
|
15 |
+
/** @var Options $opts */
|
16 |
+
$opts = $this->getOptions();
|
17 |
+
|
18 |
+
$data = [
|
19 |
+
'strings' => [
|
20 |
+
'title' => __( 'Activity Audit Log', 'wp-simple-firewall' ),
|
21 |
+
'sub' => __( 'Track Activity: What, Who, When, Where', 'wp-simple-firewall' ),
|
22 |
+
],
|
23 |
+
'key_opts' => [],
|
24 |
+
'href_options' => $mod->getUrl_AdminPage()
|
25 |
+
];
|
26 |
+
|
27 |
+
if ( !$mod->isModOptEnabled() ) {
|
28 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$aAudit = [];
|
32 |
+
$aNonAudit = [];
|
33 |
+
$opts->isAuditShield() ? $aAudit[] = 'Shield' : $aNonAudit[] = 'Shield';
|
34 |
+
$opts->isAuditUsers() ? $aAudit[] = __( 'users', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'users', 'wp-simple-firewall' );
|
35 |
+
$opts->isAuditPlugins() ? $aAudit[] = __( 'plugins', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'plugins', 'wp-simple-firewall' );
|
36 |
+
$opts->isAuditThemes() ? $aAudit[] = __( 'themes', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'themes', 'wp-simple-firewall' );
|
37 |
+
$opts->isAuditPosts() ? $aAudit[] = __( 'posts', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'posts', 'wp-simple-firewall' );
|
38 |
+
$opts->isAuditEmails() ? $aAudit[] = __( 'emails', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'emails', 'wp-simple-firewall' );
|
39 |
+
$opts->isAuditWp() ? $aAudit[] = 'WP' : $aNonAudit[] = 'WP';
|
40 |
+
|
41 |
+
if ( empty( $aNonAudit ) ) {
|
42 |
+
$data[ 'key_opts' ][ 'audit' ] = [
|
43 |
+
'name' => __( 'Audit Areas', 'wp-simple-firewall' ),
|
44 |
+
'enabled' => true,
|
45 |
+
'summary' => __( 'All important events on your site are being logged', 'wp-simple-firewall' ),
|
46 |
+
'weight' => 2,
|
47 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_enable_audit_contexts' ),
|
48 |
+
];
|
49 |
+
}
|
50 |
+
elseif ( empty( $aAudit ) ) {
|
51 |
+
$data[ 'key_opts' ][ 'audit' ] = [
|
52 |
+
'name' => __( 'Audit Areas', 'wp-simple-firewall' ),
|
53 |
+
'enabled' => false,
|
54 |
+
'summary' => sprintf( __( 'No areas are set to be audited: %s', 'wp-simple-firewall' ), implode( ', ', $aAudit ) ),
|
55 |
+
'weight' => 2,
|
56 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_enable_audit_contexts' ),
|
57 |
+
];
|
58 |
+
}
|
59 |
+
else {
|
60 |
+
$data[ 'key_opts' ][ 'nonaudit' ] = [
|
61 |
+
'name' => __( 'Audit Events', 'wp-simple-firewall' ),
|
62 |
+
'enabled' => false,
|
63 |
+
'summary' => sprintf( __( "Important events aren't being audited: %s", 'wp-simple-firewall' ), implode( ', ', $aNonAudit ) ),
|
64 |
+
'weight' => 2,
|
65 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_enable_audit_contexts' ),
|
66 |
+
];
|
67 |
+
}
|
68 |
+
|
69 |
+
$data[ 'key_opts' ][ 'length' ] = [
|
70 |
+
'name' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
71 |
+
'enabled' => true,
|
72 |
+
'summary' => sprintf( __( 'Maximum Audit Trail entries limited to %s', 'wp-simple-firewall' ), $opts->getMaxEntries() ),
|
73 |
+
'weight' => 0,
|
74 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'audit_trail_max_entries' ),
|
75 |
+
];
|
76 |
+
}
|
77 |
+
|
78 |
+
return $data;
|
79 |
+
}
|
80 |
+
}
|
src/lib/src/Modules/Autoupdates/Strings.php
CHANGED
@@ -7,15 +7,15 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
7 |
class Strings extends Base\Strings {
|
8 |
|
9 |
/**
|
10 |
-
* @param string $
|
11 |
* @return array
|
12 |
* @throws \Exception
|
13 |
*/
|
14 |
-
public function getSectionStrings( $
|
15 |
$sModName = $this->getMod()->getMainFeatureName();
|
16 |
$sPlugName = $this->getCon()->getHumanName();
|
17 |
|
18 |
-
switch ( $
|
19 |
|
20 |
case 'section_enable_plugin_feature_automatic_updates_control' :
|
21 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -65,7 +65,7 @@ class Strings extends Base\Strings {
|
|
65 |
break;
|
66 |
|
67 |
default:
|
68 |
-
return parent::getSectionStrings( $
|
69 |
}
|
70 |
|
71 |
return [
|
@@ -76,15 +76,15 @@ class Strings extends Base\Strings {
|
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
-
* @param string $
|
80 |
* @return array
|
81 |
* @throws \Exception
|
82 |
*/
|
83 |
-
public function getOptionStrings( $
|
84 |
$sModName = $this->getMod()->getMainFeatureName();
|
85 |
$sPlugName = $this->getCon()->getHumanName();
|
86 |
|
87 |
-
switch ( $
|
88 |
|
89 |
case 'enable_autoupdates' :
|
90 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -160,7 +160,7 @@ class Strings extends Base\Strings {
|
|
160 |
break;
|
161 |
|
162 |
default:
|
163 |
-
return parent::getOptionStrings( $
|
164 |
}
|
165 |
|
166 |
return [
|
7 |
class Strings extends Base\Strings {
|
8 |
|
9 |
/**
|
10 |
+
* @param string $section
|
11 |
* @return array
|
12 |
* @throws \Exception
|
13 |
*/
|
14 |
+
public function getSectionStrings( $section ) {
|
15 |
$sModName = $this->getMod()->getMainFeatureName();
|
16 |
$sPlugName = $this->getCon()->getHumanName();
|
17 |
|
18 |
+
switch ( $section ) {
|
19 |
|
20 |
case 'section_enable_plugin_feature_automatic_updates_control' :
|
21 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
65 |
break;
|
66 |
|
67 |
default:
|
68 |
+
return parent::getSectionStrings( $section );
|
69 |
}
|
70 |
|
71 |
return [
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
+
* @param string $key
|
80 |
* @return array
|
81 |
* @throws \Exception
|
82 |
*/
|
83 |
+
public function getOptionStrings( $key ) {
|
84 |
$sModName = $this->getMod()->getMainFeatureName();
|
85 |
$sPlugName = $this->getCon()->getHumanName();
|
86 |
|
87 |
+
switch ( $key ) {
|
88 |
|
89 |
case 'enable_autoupdates' :
|
90 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
160 |
break;
|
161 |
|
162 |
default:
|
163 |
+
return parent::getOptionStrings( $key );
|
164 |
}
|
165 |
|
166 |
return [
|
src/lib/src/Modules/Autoupdates/UI.php
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Autoupdates;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class UI extends Base\ShieldUI {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
public function getInsightsConfigCardData() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_Autoupdates $mod */
|
15 |
+
$mod = $this->getMod();
|
16 |
+
/** @var Options $opts */
|
17 |
+
$opts = $this->getOptions();
|
18 |
+
|
19 |
+
$data = [
|
20 |
+
'strings' => [
|
21 |
+
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
22 |
+
'sub' => __( 'Control WordPress Automatic Updates', 'wp-simple-firewall' ),
|
23 |
+
],
|
24 |
+
'key_opts' => [],
|
25 |
+
'href_options' => $mod->getUrl_AdminPage()
|
26 |
+
];
|
27 |
+
|
28 |
+
if ( !$mod->isModOptEnabled() ) {
|
29 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
30 |
+
}
|
31 |
+
elseif ( $opts->isDisableAllAutoUpdates() ) {
|
32 |
+
$data[ 'key_opts' ][ 'disabled' ] = [
|
33 |
+
'name' => __( 'Disabled All', 'wp-simple-firewall' ),
|
34 |
+
'enabled' => false,
|
35 |
+
'summary' => __( 'All automatic updates on this site are disabled', 'wp-simple-firewall' ),
|
36 |
+
'weight' => 2,
|
37 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'enable_autoupdate_disable_all' ),
|
38 |
+
];
|
39 |
+
}
|
40 |
+
else {
|
41 |
+
$bCanCore = Services::WpGeneral()->canCoreUpdateAutomatically();
|
42 |
+
$data[ 'key_opts' ][ 'core_minor' ] = [
|
43 |
+
'name' => __( 'Core Updates', 'wp-simple-firewall' ),
|
44 |
+
'enabled' => $bCanCore,
|
45 |
+
'summary' => $bCanCore ?
|
46 |
+
__( 'Minor WP Core updates will be installed automatically', 'wp-simple-firewall' )
|
47 |
+
: __( 'Minor WP Core updates will not be installed automatically', 'wp-simple-firewall' ),
|
48 |
+
'weight' => 2,
|
49 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'autoupdate_core' ),
|
50 |
+
];
|
51 |
+
|
52 |
+
$bHasDelay = $mod->isModOptEnabled() && $opts->getDelayUpdatesPeriod();
|
53 |
+
$data[ 'key_opts' ][ 'delay' ] = [
|
54 |
+
'name' => __( 'Update Delay', 'wp-simple-firewall' ),
|
55 |
+
'enabled' => $bHasDelay,
|
56 |
+
'summary' => $bHasDelay ?
|
57 |
+
__( 'Automatic updates are applied after a short delay', 'wp-simple-firewall' )
|
58 |
+
: __( 'Automatic updates are applied immediately', 'wp-simple-firewall' ),
|
59 |
+
'weight' => 1,
|
60 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'update_delay' ),
|
61 |
+
];
|
62 |
+
|
63 |
+
$sName = $this->getCon()->getHumanName();
|
64 |
+
$bSelfAuto = $mod->isModOptEnabled()
|
65 |
+
&& in_array( $opts->getSelfAutoUpdateOpt(), [ 'auto', 'immediate' ] );
|
66 |
+
$data[ 'key_opts' ][ 'self' ] = [
|
67 |
+
'name' => __( 'Self Auto-Update', 'wp-simple-firewall' ),
|
68 |
+
'enabled' => $bSelfAuto,
|
69 |
+
'summary' => $bSelfAuto ?
|
70 |
+
sprintf( __( '%s is automatically updated', 'wp-simple-firewall' ), $sName )
|
71 |
+
: sprintf( __( "%s isn't automatically updated", 'wp-simple-firewall' ), $sName ),
|
72 |
+
'weight' => 1,
|
73 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'autoupdate_plugin_self' ),
|
74 |
+
];
|
75 |
+
}
|
76 |
+
|
77 |
+
return $data;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return array
|
82 |
+
*/
|
83 |
+
public function getInsightsNoticesData() {
|
84 |
+
/** @var \ICWP_WPSF_FeatureHandler_Autoupdates $mod */
|
85 |
+
$mod = $this->getMod();
|
86 |
+
/** @var Options $opts */
|
87 |
+
$opts = $this->getOptions();
|
88 |
+
|
89 |
+
$notices = [
|
90 |
+
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
91 |
+
'messages' => []
|
92 |
+
];
|
93 |
+
|
94 |
+
{ //really disabled?
|
95 |
+
$WP = Services::WpGeneral();
|
96 |
+
if ( $mod->isModOptEnabled() ) {
|
97 |
+
if ( $opts->isDisableAllAutoUpdates() && !$WP->getWpAutomaticUpdater()->is_disabled() ) {
|
98 |
+
$notices[ 'messages' ][ 'disabled_auto' ] = [
|
99 |
+
'title' => 'Auto Updates Not Really Disabled',
|
100 |
+
'message' => __( 'Automatic Updates Are Not Disabled As Expected.', 'wp-simple-firewall' ),
|
101 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'enable_autoupdate_disable_all' ),
|
102 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
103 |
+
'rec' => sprintf( __( 'A plugin/theme other than %s is affecting your automatic update settings.', 'wp-simple-firewall' ), $this->getCon()
|
104 |
+
->getHumanName() )
|
105 |
+
];
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
return $notices;
|
111 |
+
}
|
112 |
+
}
|
src/lib/src/Modules/Base/AdminNotices.php
CHANGED
@@ -10,15 +10,11 @@ class AdminNotices {
|
|
10 |
|
11 |
use Shield\Modules\ModConsumer;
|
12 |
|
13 |
-
/**
|
14 |
-
* @var
|
15 |
-
*/
|
16 |
protected static $nCount = 0;
|
17 |
|
18 |
public function run() {
|
19 |
-
|
20 |
-
add_filter( $
|
21 |
-
add_filter( $oMod->prefix( 'ajaxAuthAction' ), [ $this, 'handleAuthAjax' ] );
|
22 |
}
|
23 |
|
24 |
/**
|
@@ -70,13 +66,13 @@ class AdminNotices {
|
|
70 |
protected function buildNotices() {
|
71 |
$aNotices = [];
|
72 |
|
73 |
-
foreach ( $this->getAdminNotices() as $
|
74 |
-
$this->preProcessNotice( $
|
75 |
-
if ( $
|
76 |
try {
|
77 |
-
$this->processNotice( $
|
78 |
-
if ( $
|
79 |
-
$aNotices[] = $
|
80 |
}
|
81 |
}
|
82 |
catch ( \Exception $oE ) {
|
@@ -116,61 +112,60 @@ class AdminNotices {
|
|
116 |
}
|
117 |
|
118 |
/**
|
119 |
-
* @param Shield\Utilities\AdminNotices\NoticeVO $
|
120 |
*/
|
121 |
-
protected function preProcessNotice( $
|
122 |
-
$
|
123 |
-
$
|
124 |
-
$oOpts = $oMod->getOptions();
|
125 |
|
126 |
-
if ( $
|
127 |
-
$
|
128 |
}
|
129 |
-
elseif ( $
|
130 |
-
$
|
131 |
}
|
132 |
-
elseif ( $
|
133 |
-
$
|
134 |
}
|
135 |
-
elseif ( $
|
136 |
-
$
|
137 |
}
|
138 |
-
elseif ( $
|
139 |
-
$
|
140 |
}
|
141 |
-
elseif ( $
|
142 |
-
$
|
143 |
}
|
144 |
-
elseif ( static::$nCount > 0 && $
|
145 |
-
$
|
146 |
}
|
147 |
-
elseif ( $
|
148 |
-
$
|
149 |
}
|
150 |
-
elseif ( !$this->isDisplayNeeded( $
|
151 |
-
$
|
152 |
}
|
153 |
else {
|
154 |
static::$nCount++;
|
155 |
-
$
|
156 |
-
$
|
157 |
}
|
158 |
|
159 |
-
$
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
-
* @param Shield\Utilities\AdminNotices\NoticeVO $
|
164 |
* @return bool
|
165 |
*/
|
166 |
-
protected function isNoticeDismissed( $
|
167 |
-
$bDismissedUser = $this->isNoticeDismissedForCurrentUser( $
|
168 |
|
169 |
$aDisd = $this->getMod()->getDismissedNotices();
|
170 |
-
$bDismissedMod = isset( $aDisd[ $
|
171 |
|
172 |
-
if ( !$
|
173 |
-
$this->setNoticeDismissed( $
|
174 |
}
|
175 |
|
176 |
return $bDismissedUser || $bDismissedMod;
|
@@ -185,22 +180,22 @@ class AdminNotices {
|
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
-
* @param Shield\Utilities\AdminNotices\NoticeVO $
|
189 |
* @return bool
|
190 |
*/
|
191 |
-
protected function isNoticeDismissedForCurrentUser( $
|
192 |
$bDismissed = false;
|
193 |
|
194 |
-
$
|
195 |
-
if ( $
|
196 |
-
$sNoticeMetaKey = $this->getNoticeMetaKey( $
|
197 |
|
198 |
-
if ( isset( $
|
199 |
$bDismissed = true;
|
200 |
|
201 |
// migrate from old-style array storage to plain Timestamp
|
202 |
-
if ( is_array( $
|
203 |
-
$
|
204 |
}
|
205 |
}
|
206 |
}
|
@@ -217,39 +212,39 @@ class AdminNotices {
|
|
217 |
}
|
218 |
|
219 |
/**
|
220 |
-
* @param Shield\Utilities\AdminNotices\NoticeVO $
|
221 |
* @return $this
|
222 |
*/
|
223 |
-
protected function setNoticeDismissed( $
|
224 |
$nTs = Services::Request()->ts();
|
225 |
|
226 |
-
$
|
227 |
-
$sNoticeMetaKey = $this->getNoticeMetaKey( $
|
228 |
|
229 |
-
if ( $
|
230 |
-
if ( $
|
231 |
-
$
|
232 |
}
|
233 |
}
|
234 |
else {
|
235 |
-
$
|
236 |
-
$aDismissed = $
|
237 |
-
$aDismissed[ $
|
238 |
-
$
|
239 |
|
240 |
// Clear out any old
|
241 |
-
if ( $
|
242 |
-
unset( $
|
243 |
}
|
244 |
}
|
245 |
return $this;
|
246 |
}
|
247 |
|
248 |
/**
|
249 |
-
* @param Shield\Utilities\AdminNotices\NoticeVO $
|
250 |
* @return string
|
251 |
*/
|
252 |
-
private function getNoticeMetaKey( $
|
253 |
-
return 'notice_'.str_replace( [ '-', '_' ], '', $
|
254 |
}
|
255 |
}
|
10 |
|
11 |
use Shield\Modules\ModConsumer;
|
12 |
|
|
|
|
|
|
|
13 |
protected static $nCount = 0;
|
14 |
|
15 |
public function run() {
|
16 |
+
add_filter( $this->getCon()->prefix( 'collectNotices' ), [ $this, 'addNotices' ] );
|
17 |
+
add_filter( $this->getCon()->prefix( 'ajaxAuthAction' ), [ $this, 'handleAuthAjax' ] );
|
|
|
18 |
}
|
19 |
|
20 |
/**
|
66 |
protected function buildNotices() {
|
67 |
$aNotices = [];
|
68 |
|
69 |
+
foreach ( $this->getAdminNotices() as $notice ) {
|
70 |
+
$this->preProcessNotice( $notice );
|
71 |
+
if ( $notice->display ) {
|
72 |
try {
|
73 |
+
$this->processNotice( $notice );
|
74 |
+
if ( $notice->display ) {
|
75 |
+
$aNotices[] = $notice;
|
76 |
}
|
77 |
}
|
78 |
catch ( \Exception $oE ) {
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $notice
|
116 |
*/
|
117 |
+
protected function preProcessNotice( $notice ) {
|
118 |
+
$con = $this->getCon();
|
119 |
+
$opts = $this->getOptions();
|
|
|
120 |
|
121 |
+
if ( $notice->plugin_page_only && !$con->isModulePage() ) {
|
122 |
+
$notice->non_display_reason = 'plugin_page_only';
|
123 |
}
|
124 |
+
elseif ( $notice->type == 'promo' && !$opts->isShowPromoAdminNotices() ) {
|
125 |
+
$notice->non_display_reason = 'promo_hidden';
|
126 |
}
|
127 |
+
elseif ( $notice->valid_admin && !$con->isValidAdminArea() ) {
|
128 |
+
$notice->non_display_reason = 'not_admin_area';
|
129 |
}
|
130 |
+
elseif ( $notice->plugin_admin == 'yes' && !$con->isPluginAdmin() ) {
|
131 |
+
$notice->non_display_reason = 'not_plugin_admin';
|
132 |
}
|
133 |
+
elseif ( $notice->plugin_admin == 'no' && $con->isPluginAdmin() ) {
|
134 |
+
$notice->non_display_reason = 'is_plugin_admin';
|
135 |
}
|
136 |
+
elseif ( $notice->min_install_days > 0 && $notice->min_install_days > $opts->getInstallationDays() ) {
|
137 |
+
$notice->non_display_reason = 'min_install_days';
|
138 |
}
|
139 |
+
elseif ( static::$nCount > 0 && $notice->type !== 'error' ) {
|
140 |
+
$notice->non_display_reason = 'max_nonerror_count';
|
141 |
}
|
142 |
+
elseif ( $notice->can_dismiss && $this->isNoticeDismissed( $notice ) ) {
|
143 |
+
$notice->non_display_reason = 'dismissed';
|
144 |
}
|
145 |
+
elseif ( !$this->isDisplayNeeded( $notice ) ) {
|
146 |
+
$notice->non_display_reason = 'not_needed';
|
147 |
}
|
148 |
else {
|
149 |
static::$nCount++;
|
150 |
+
$notice->display = true;
|
151 |
+
$notice->non_display_reason = 'n/a';
|
152 |
}
|
153 |
|
154 |
+
$notice->template = '/notices/'.$notice->id;
|
155 |
}
|
156 |
|
157 |
/**
|
158 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $notice
|
159 |
* @return bool
|
160 |
*/
|
161 |
+
protected function isNoticeDismissed( $notice ) {
|
162 |
+
$bDismissedUser = $this->isNoticeDismissedForCurrentUser( $notice );
|
163 |
|
164 |
$aDisd = $this->getMod()->getDismissedNotices();
|
165 |
+
$bDismissedMod = isset( $aDisd[ $notice->id ] ) && $aDisd[ $notice->id ] > 0;
|
166 |
|
167 |
+
if ( !$notice->per_user && $bDismissedUser && !$bDismissedMod ) {
|
168 |
+
$this->setNoticeDismissed( $notice );
|
169 |
}
|
170 |
|
171 |
return $bDismissedUser || $bDismissedMod;
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $notice
|
184 |
* @return bool
|
185 |
*/
|
186 |
+
protected function isNoticeDismissedForCurrentUser( $notice ) {
|
187 |
$bDismissed = false;
|
188 |
|
189 |
+
$meta = $this->getCon()->getCurrentUserMeta();
|
190 |
+
if ( $meta instanceof PluginUserMeta ) {
|
191 |
+
$sNoticeMetaKey = $this->getNoticeMetaKey( $notice );
|
192 |
|
193 |
+
if ( isset( $meta->{$sNoticeMetaKey} ) ) {
|
194 |
$bDismissed = true;
|
195 |
|
196 |
// migrate from old-style array storage to plain Timestamp
|
197 |
+
if ( is_array( $meta->{$sNoticeMetaKey} ) ) {
|
198 |
+
$meta->{$sNoticeMetaKey} = $meta->{$sNoticeMetaKey}[ 'time' ];
|
199 |
}
|
200 |
}
|
201 |
}
|
212 |
}
|
213 |
|
214 |
/**
|
215 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $notice
|
216 |
* @return $this
|
217 |
*/
|
218 |
+
protected function setNoticeDismissed( $notice ) {
|
219 |
$nTs = Services::Request()->ts();
|
220 |
|
221 |
+
$meta = $this->getCon()->getCurrentUserMeta();
|
222 |
+
$sNoticeMetaKey = $this->getNoticeMetaKey( $notice );
|
223 |
|
224 |
+
if ( $notice->per_user ) {
|
225 |
+
if ( $meta instanceof PluginUserMeta ) {
|
226 |
+
$meta->{$sNoticeMetaKey} = $nTs;
|
227 |
}
|
228 |
}
|
229 |
else {
|
230 |
+
$mod = $this->getMod();
|
231 |
+
$aDismissed = $mod->getDismissedNotices();
|
232 |
+
$aDismissed[ $notice->id ] = $nTs;
|
233 |
+
$mod->setDismissedNotices( $aDismissed );
|
234 |
|
235 |
// Clear out any old
|
236 |
+
if ( $meta instanceof PluginUserMeta ) {
|
237 |
+
unset( $meta->{$sNoticeMetaKey} );
|
238 |
}
|
239 |
}
|
240 |
return $this;
|
241 |
}
|
242 |
|
243 |
/**
|
244 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $notice
|
245 |
* @return string
|
246 |
*/
|
247 |
+
private function getNoticeMetaKey( $notice ) {
|
248 |
+
return 'notice_'.str_replace( [ '-', '_' ], '', $notice->id );
|
249 |
}
|
250 |
}
|
src/lib/src/Modules/Base/AjaxHandlerBase.php
CHANGED
@@ -13,8 +13,6 @@ class AjaxHandlerBase {
|
|
13 |
add_action( 'wp_loaded', [ $this, 'init' ] );
|
14 |
}
|
15 |
|
16 |
-
/**
|
17 |
-
*/
|
18 |
public function init() {
|
19 |
add_filter( $this->getCon()->prefix( 'ajaxAuthAction' ), [ $this, 'handleAjaxAuth' ], 10, 2 );
|
20 |
add_filter( $this->getCon()->prefix( 'ajaxNonAuthAction' ), [ $this, 'handleAjaxNonAuth' ], 10, 2 );
|
@@ -80,10 +78,10 @@ class AjaxHandlerBase {
|
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
-
* @param string $
|
84 |
* @return array
|
85 |
*/
|
86 |
-
protected function processAjaxAction( $
|
87 |
return [];
|
88 |
}
|
89 |
|
13 |
add_action( 'wp_loaded', [ $this, 'init' ] );
|
14 |
}
|
15 |
|
|
|
|
|
16 |
public function init() {
|
17 |
add_filter( $this->getCon()->prefix( 'ajaxAuthAction' ), [ $this, 'handleAjaxAuth' ], 10, 2 );
|
18 |
add_filter( $this->getCon()->prefix( 'ajaxNonAuthAction' ), [ $this, 'handleAjaxNonAuth' ], 10, 2 );
|
78 |
}
|
79 |
|
80 |
/**
|
81 |
+
* @param string $action
|
82 |
* @return array
|
83 |
*/
|
84 |
+
protected function processAjaxAction( $action ) {
|
85 |
return [];
|
86 |
}
|
87 |
|
src/lib/src/Modules/Base/AjaxHandlerShield.php
CHANGED
@@ -5,14 +5,14 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
5 |
class AjaxHandlerShield extends AjaxHandlerBase {
|
6 |
|
7 |
/**
|
8 |
-
* @param string $
|
9 |
* @return array
|
10 |
*/
|
11 |
-
protected function processAjaxAction( $
|
12 |
$aResponse = [];
|
13 |
-
$
|
14 |
|
15 |
-
switch ( $
|
16 |
|
17 |
case 'mod_opts_form_render':
|
18 |
$aResponse = $this->ajaxExec_ModOptionsFormRender();
|
@@ -23,21 +23,21 @@ class AjaxHandlerShield extends AjaxHandlerBase {
|
|
23 |
break;
|
24 |
|
25 |
case 'wiz_process_step':
|
26 |
-
if ( $
|
27 |
-
$aResponse = $
|
28 |
->ajaxExec_WizProcessStep();
|
29 |
}
|
30 |
break;
|
31 |
|
32 |
case 'wiz_render_step':
|
33 |
-
if ( $
|
34 |
-
$aResponse = $
|
35 |
->ajaxExec_WizRenderStep();
|
36 |
}
|
37 |
break;
|
38 |
|
39 |
default:
|
40 |
-
$aResponse = parent::processAjaxAction( $
|
41 |
}
|
42 |
|
43 |
return $aResponse;
|
5 |
class AjaxHandlerShield extends AjaxHandlerBase {
|
6 |
|
7 |
/**
|
8 |
+
* @param string $action
|
9 |
* @return array
|
10 |
*/
|
11 |
+
protected function processAjaxAction( $action ) {
|
12 |
$aResponse = [];
|
13 |
+
$mod = $this->getMod();
|
14 |
|
15 |
+
switch ( $action ) {
|
16 |
|
17 |
case 'mod_opts_form_render':
|
18 |
$aResponse = $this->ajaxExec_ModOptionsFormRender();
|
23 |
break;
|
24 |
|
25 |
case 'wiz_process_step':
|
26 |
+
if ( $mod->hasWizard() ) {
|
27 |
+
$aResponse = $mod->getWizardHandler()
|
28 |
->ajaxExec_WizProcessStep();
|
29 |
}
|
30 |
break;
|
31 |
|
32 |
case 'wiz_render_step':
|
33 |
+
if ( $mod->hasWizard() ) {
|
34 |
+
$aResponse = $mod->getWizardHandler()
|
35 |
->ajaxExec_WizRenderStep();
|
36 |
}
|
37 |
break;
|
38 |
|
39 |
default:
|
40 |
+
$aResponse = parent::processAjaxAction( $action );
|
41 |
}
|
42 |
|
43 |
return $aResponse;
|
src/lib/src/Modules/Base/BaseModCon.php
CHANGED
@@ -112,9 +112,6 @@ class BaseModCon {
|
|
112 |
|
113 |
$nMenuPri = isset( $aModProps[ 'menu_priority' ] ) ? $aModProps[ 'menu_priority' ] : 100;
|
114 |
add_filter( $this->prefix( 'submenu_items' ), [ $this, 'supplySubMenuItem' ], $nMenuPri );
|
115 |
-
add_filter( $this->prefix( 'collect_mod_summary' ), [ $this, 'addModuleSummaryData' ], $nMenuPri );
|
116 |
-
add_filter( $this->prefix( 'collect_notices' ), [ $this, 'addInsightsNoticeData' ] );
|
117 |
-
add_filter( $this->prefix( 'collect_summary' ), [ $this, 'addInsightsConfigData' ], $nRunPriority );
|
118 |
add_action( $this->prefix( 'plugin_shutdown' ), [ $this, 'onPluginShutdown' ] );
|
119 |
add_action( $this->prefix( 'deactivate_plugin' ), [ $this, 'onPluginDeactivate' ] );
|
120 |
add_action( $this->prefix( 'delete_plugin' ), [ $this, 'onPluginDelete' ] );
|
@@ -305,8 +302,6 @@ class BaseModCon {
|
|
305 |
return $bMeetsReqs;
|
306 |
}
|
307 |
|
308 |
-
/**
|
309 |
-
*/
|
310 |
public function onRunProcessors() {
|
311 |
if ( $this->isUpgrading() ) {
|
312 |
$this->updateHandler();
|
@@ -354,8 +349,6 @@ class BaseModCon {
|
|
354 |
add_action( 'load-'.$page_hook, [ $this, 'onLoadOptionsScreen' ] );
|
355 |
}
|
356 |
|
357 |
-
/**
|
358 |
-
*/
|
359 |
public function onLoadOptionsScreen() {
|
360 |
if ( $this->getCon()->isValidAdminArea() ) {
|
361 |
$this->buildContextualHelp();
|
@@ -651,55 +644,6 @@ class BaseModCon {
|
|
651 |
return $aAllData;
|
652 |
}
|
653 |
|
654 |
-
/**
|
655 |
-
* @return array
|
656 |
-
*/
|
657 |
-
protected function buildSummaryData() {
|
658 |
-
$oOptsVo = $this->getOptions();
|
659 |
-
$sMenuTitle = $oOptsVo->getFeatureProperty( 'menu_title' );
|
660 |
-
|
661 |
-
$aSections = $oOptsVo->getSections();
|
662 |
-
foreach ( $aSections as $sSlug => $aSection ) {
|
663 |
-
try {
|
664 |
-
$aStrings = $this->getStrings()->getSectionStrings( $aSection[ 'slug' ] );
|
665 |
-
foreach ( $aStrings as $sKey => $sVal ) {
|
666 |
-
unset( $aSection[ $sKey ] );
|
667 |
-
$aSection[ $sKey ] = $sVal;
|
668 |
-
}
|
669 |
-
}
|
670 |
-
catch ( \Exception $oE ) {
|
671 |
-
}
|
672 |
-
}
|
673 |
-
|
674 |
-
$aSum = [
|
675 |
-
'enabled' => $this->isEnabledForUiSummary(),
|
676 |
-
'active' => $this->isThisModulePage() || $this->isPage_InsightsThisModule(),
|
677 |
-
'slug' => $this->getSlug(),
|
678 |
-
'name' => $this->getMainFeatureName(),
|
679 |
-
'menu_title' => empty( $sMenuTitle ) ? $this->getMainFeatureName() : __( $sMenuTitle, 'wp-simple-firewall' ),
|
680 |
-
'href' => network_admin_url( 'admin.php?page='.$this->getModSlug() ),
|
681 |
-
'sections' => $aSections,
|
682 |
-
'options' => [],
|
683 |
-
];
|
684 |
-
|
685 |
-
foreach ( $oOptsVo->getVisibleOptionsKeys() as $sOptKey ) {
|
686 |
-
try {
|
687 |
-
$aOptData = $this->getStrings()->getOptionStrings( $sOptKey );
|
688 |
-
$aOptData[ 'href' ] = $this->getUrl_DirectLinkToOption( $sOptKey );
|
689 |
-
$aSum[ 'options' ][ $sOptKey ] = $aOptData;
|
690 |
-
}
|
691 |
-
catch ( \Exception $oE ) {
|
692 |
-
}
|
693 |
-
}
|
694 |
-
|
695 |
-
$aSum[ 'tooltip' ] = sprintf(
|
696 |
-
'%s%s',
|
697 |
-
$aSum[ 'name' ],
|
698 |
-
( $aSum[ 'enabled' ] ? '' : ' ('.strtolower( __( 'Disabled', 'wp-simple-firewall' ) ).')' )
|
699 |
-
);
|
700 |
-
return $aSum;
|
701 |
-
}
|
702 |
-
|
703 |
/**
|
704 |
* @return bool
|
705 |
*/
|
@@ -949,168 +893,12 @@ class BaseModCon {
|
|
949 |
return array_merge( $aAggregatedOptions, $this->getOptions()->getAllOptionsValues() );
|
950 |
}
|
951 |
|
952 |
-
/**
|
953 |
-
* Will initiate the plugin options structure for use by the UI builder.
|
954 |
-
* It doesn't set any values, just populates the array created in buildOptions()
|
955 |
-
* with values stored.
|
956 |
-
* It has to handle the conversion of stored values to data to be displayed to the user.
|
957 |
-
*/
|
958 |
-
public function buildOptions() {
|
959 |
-
|
960 |
-
$bPremiumEnabled = $this->getCon()->isPremiumExtensionsEnabled();
|
961 |
-
|
962 |
-
$oOptsVo = $this->getOptions();
|
963 |
-
$aOptions = $oOptsVo->getOptionsForPluginUse();
|
964 |
-
|
965 |
-
foreach ( $aOptions as $nSectionKey => $aSection ) {
|
966 |
-
|
967 |
-
if ( !empty( $aSection[ 'options' ] ) ) {
|
968 |
-
|
969 |
-
foreach ( $aSection[ 'options' ] as $nKey => $aOption ) {
|
970 |
-
$aOption[ 'is_value_default' ] = ( $aOption[ 'value' ] === $aOption[ 'default' ] );
|
971 |
-
$bIsPrem = isset( $aOption[ 'premium' ] ) && $aOption[ 'premium' ];
|
972 |
-
if ( !$bIsPrem || $bPremiumEnabled ) {
|
973 |
-
$aSection[ 'options' ][ $nKey ] = $this->buildOptionForUi( $aOption );
|
974 |
-
}
|
975 |
-
else {
|
976 |
-
unset( $aSection[ 'options' ][ $nKey ] );
|
977 |
-
}
|
978 |
-
}
|
979 |
-
|
980 |
-
if ( empty( $aSection[ 'options' ] ) ) {
|
981 |
-
unset( $aOptions[ $nSectionKey ] );
|
982 |
-
}
|
983 |
-
else {
|
984 |
-
try {
|
985 |
-
$aStrings = $this->getStrings()->getSectionStrings( $aSection[ 'slug' ] );
|
986 |
-
foreach ( $aStrings as $sKey => $sVal ) {
|
987 |
-
unset( $aSection[ $sKey ] );
|
988 |
-
$aSection[ $sKey ] = $sVal;
|
989 |
-
}
|
990 |
-
}
|
991 |
-
catch ( \Exception $oE ) {
|
992 |
-
}
|
993 |
-
$aOptions[ $nSectionKey ] = $aSection;
|
994 |
-
}
|
995 |
-
|
996 |
-
$aWarnings = [];
|
997 |
-
if ( !$oOptsVo->isSectionReqsMet( $aSection[ 'slug' ] ) ) {
|
998 |
-
$aWarnings[] = __( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.', 'wp-simple-firewall' );
|
999 |
-
}
|
1000 |
-
$aOptions[ $nSectionKey ][ 'warnings' ] = array_merge(
|
1001 |
-
$aWarnings,
|
1002 |
-
$this->getSectionWarnings( $aSection[ 'slug' ] )
|
1003 |
-
);
|
1004 |
-
$aOptions[ $nSectionKey ][ 'notices' ] = $this->getSectionNotices( $aSection[ 'slug' ] );
|
1005 |
-
|
1006 |
-
if ( !empty( $aSection[ 'help_video_id' ] ) ) {
|
1007 |
-
$sHelpVideoUrl = $this->getHelpVideoUrl( $aSection[ 'help_video_id' ] );
|
1008 |
-
}
|
1009 |
-
else {
|
1010 |
-
$sHelpVideoUrl = '';
|
1011 |
-
}
|
1012 |
-
$aOptions[ $nSectionKey ][ 'help_video_url' ] = $sHelpVideoUrl;
|
1013 |
-
}
|
1014 |
-
}
|
1015 |
-
|
1016 |
-
return $aOptions;
|
1017 |
-
}
|
1018 |
-
|
1019 |
-
/**
|
1020 |
-
* @param string $sSectionSlug
|
1021 |
-
* @return array
|
1022 |
-
*/
|
1023 |
-
protected function getSectionNotices( $sSectionSlug ) {
|
1024 |
-
return [];
|
1025 |
-
}
|
1026 |
-
|
1027 |
-
/**
|
1028 |
-
* @param string $sSection
|
1029 |
-
* @return array
|
1030 |
-
*/
|
1031 |
-
protected function getSectionWarnings( $sSection ) {
|
1032 |
-
return [];
|
1033 |
-
}
|
1034 |
-
|
1035 |
-
/**
|
1036 |
-
* @param array $aOptParams
|
1037 |
-
* @return array
|
1038 |
-
*/
|
1039 |
-
protected function buildOptionForUi( $aOptParams ) {
|
1040 |
-
|
1041 |
-
$mCurrent = $aOptParams[ 'value' ];
|
1042 |
-
|
1043 |
-
switch ( $aOptParams[ 'type' ] ) {
|
1044 |
-
|
1045 |
-
case 'password':
|
1046 |
-
if ( !empty( $mCurrent ) ) {
|
1047 |
-
$mCurrent = '';
|
1048 |
-
}
|
1049 |
-
break;
|
1050 |
-
|
1051 |
-
case 'array':
|
1052 |
-
|
1053 |
-
if ( empty( $mCurrent ) || !is_array( $mCurrent ) ) {
|
1054 |
-
$mCurrent = [];
|
1055 |
-
}
|
1056 |
-
|
1057 |
-
$aOptParams[ 'rows' ] = count( $mCurrent ) + 2;
|
1058 |
-
$mCurrent = stripslashes( implode( "\n", $mCurrent ) );
|
1059 |
-
|
1060 |
-
break;
|
1061 |
-
|
1062 |
-
case 'comma_separated_lists':
|
1063 |
-
|
1064 |
-
$aNewValues = [];
|
1065 |
-
if ( !empty( $mCurrent ) && is_array( $mCurrent ) ) {
|
1066 |
-
|
1067 |
-
foreach ( $mCurrent as $sPage => $aParams ) {
|
1068 |
-
$aNewValues[] = $sPage.', '.implode( ", ", $aParams );
|
1069 |
-
}
|
1070 |
-
}
|
1071 |
-
$aOptParams[ 'rows' ] = count( $aNewValues ) + 1;
|
1072 |
-
$mCurrent = implode( "\n", $aNewValues );
|
1073 |
-
|
1074 |
-
break;
|
1075 |
-
|
1076 |
-
case 'multiple_select':
|
1077 |
-
if ( !is_array( $mCurrent ) ) {
|
1078 |
-
$mCurrent = [];
|
1079 |
-
}
|
1080 |
-
break;
|
1081 |
-
|
1082 |
-
case 'text':
|
1083 |
-
$mCurrent = stripslashes( $this->getTextOpt( $aOptParams[ 'key' ] ) );
|
1084 |
-
break;
|
1085 |
-
}
|
1086 |
-
|
1087 |
-
$aParams = [
|
1088 |
-
'value' => is_scalar( $mCurrent ) ? esc_attr( $mCurrent ) : $mCurrent,
|
1089 |
-
'disabled' => !$this->isPremium() && ( isset( $aOptParams[ 'premium' ] ) && $aOptParams[ 'premium' ] ),
|
1090 |
-
];
|
1091 |
-
$aParams[ 'enabled' ] = !$aParams[ 'disabled' ];
|
1092 |
-
$aOptParams = array_merge( [ 'rows' => 2 ], $aOptParams, $aParams );
|
1093 |
-
|
1094 |
-
// add strings
|
1095 |
-
try {
|
1096 |
-
$aOptParams = Services::DataManipulation()->mergeArraysRecursive(
|
1097 |
-
$aOptParams,
|
1098 |
-
$this->getStrings()->getOptionStrings( $aOptParams[ 'key' ] )
|
1099 |
-
);
|
1100 |
-
}
|
1101 |
-
catch ( \Exception $oE ) {
|
1102 |
-
}
|
1103 |
-
return $aOptParams;
|
1104 |
-
}
|
1105 |
-
|
1106 |
/**
|
1107 |
* This is the point where you would want to do any options verification
|
1108 |
*/
|
1109 |
protected function doPrePluginOptionsSave() {
|
1110 |
}
|
1111 |
|
1112 |
-
/**
|
1113 |
-
*/
|
1114 |
public function onPluginDeactivate() {
|
1115 |
}
|
1116 |
|
@@ -1135,8 +923,6 @@ class BaseModCon {
|
|
1135 |
return $aOpts;
|
1136 |
}
|
1137 |
|
1138 |
-
/**
|
1139 |
-
*/
|
1140 |
public function handleModRequest() {
|
1141 |
}
|
1142 |
|
@@ -1256,8 +1042,6 @@ class BaseModCon {
|
|
1256 |
}
|
1257 |
}
|
1258 |
|
1259 |
-
/**
|
1260 |
-
*/
|
1261 |
protected function runWizards() {
|
1262 |
if ( $this->isWizardPage() && $this->hasWizard() ) {
|
1263 |
$oWiz = $this->getWizardHandler();
|
@@ -1386,7 +1170,6 @@ class BaseModCon {
|
|
1386 |
'width' => 772,
|
1387 |
'height' => 454,
|
1388 |
],
|
1389 |
-
'aSummaryData' => $this->getModulesSummaryData(),
|
1390 |
|
1391 |
// 'sPageTitle' => sprintf( '%s: %s', $oCon->getHumanName(), $this->getMainFeatureName() ),
|
1392 |
'sPageTitle' => $this->getMainFeatureName(),
|
@@ -1463,13 +1246,6 @@ class BaseModCon {
|
|
1463 |
);
|
1464 |
}
|
1465 |
|
1466 |
-
/**
|
1467 |
-
* @return array[]
|
1468 |
-
*/
|
1469 |
-
protected function getModulesSummaryData() {
|
1470 |
-
return apply_filters( $this->prefix( 'collect_mod_summary' ), [] );
|
1471 |
-
}
|
1472 |
-
|
1473 |
/**
|
1474 |
* @param string $sWizardSlug
|
1475 |
* @return string
|
112 |
|
113 |
$nMenuPri = isset( $aModProps[ 'menu_priority' ] ) ? $aModProps[ 'menu_priority' ] : 100;
|
114 |
add_filter( $this->prefix( 'submenu_items' ), [ $this, 'supplySubMenuItem' ], $nMenuPri );
|
|
|
|
|
|
|
115 |
add_action( $this->prefix( 'plugin_shutdown' ), [ $this, 'onPluginShutdown' ] );
|
116 |
add_action( $this->prefix( 'deactivate_plugin' ), [ $this, 'onPluginDeactivate' ] );
|
117 |
add_action( $this->prefix( 'delete_plugin' ), [ $this, 'onPluginDelete' ] );
|
302 |
return $bMeetsReqs;
|
303 |
}
|
304 |
|
|
|
|
|
305 |
public function onRunProcessors() {
|
306 |
if ( $this->isUpgrading() ) {
|
307 |
$this->updateHandler();
|
349 |
add_action( 'load-'.$page_hook, [ $this, 'onLoadOptionsScreen' ] );
|
350 |
}
|
351 |
|
|
|
|
|
352 |
public function onLoadOptionsScreen() {
|
353 |
if ( $this->getCon()->isValidAdminArea() ) {
|
354 |
$this->buildContextualHelp();
|
644 |
return $aAllData;
|
645 |
}
|
646 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
647 |
/**
|
648 |
* @return bool
|
649 |
*/
|
893 |
return array_merge( $aAggregatedOptions, $this->getOptions()->getAllOptionsValues() );
|
894 |
}
|
895 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
896 |
/**
|
897 |
* This is the point where you would want to do any options verification
|
898 |
*/
|
899 |
protected function doPrePluginOptionsSave() {
|
900 |
}
|
901 |
|
|
|
|
|
902 |
public function onPluginDeactivate() {
|
903 |
}
|
904 |
|
923 |
return $aOpts;
|
924 |
}
|
925 |
|
|
|
|
|
926 |
public function handleModRequest() {
|
927 |
}
|
928 |
|
1042 |
}
|
1043 |
}
|
1044 |
|
|
|
|
|
1045 |
protected function runWizards() {
|
1046 |
if ( $this->isWizardPage() && $this->hasWizard() ) {
|
1047 |
$oWiz = $this->getWizardHandler();
|
1170 |
'width' => 772,
|
1171 |
'height' => 454,
|
1172 |
],
|
|
|
1173 |
|
1174 |
// 'sPageTitle' => sprintf( '%s: %s', $oCon->getHumanName(), $this->getMainFeatureName() ),
|
1175 |
'sPageTitle' => $this->getMainFeatureName(),
|
1246 |
);
|
1247 |
}
|
1248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1249 |
/**
|
1250 |
* @param string $sWizardSlug
|
1251 |
* @return string
|
src/lib/src/Modules/Base/BaseProcessor.php
CHANGED
@@ -108,8 +108,6 @@ class BaseProcessor {
|
|
108 |
public function onModuleShutdown() {
|
109 |
}
|
110 |
|
111 |
-
/**
|
112 |
-
*/
|
113 |
public function init() {
|
114 |
}
|
115 |
|
@@ -175,8 +173,6 @@ class BaseProcessor {
|
|
175 |
return [];
|
176 |
}
|
177 |
|
178 |
-
/**
|
179 |
-
*/
|
180 |
public function deactivatePlugin() {
|
181 |
}
|
182 |
|
@@ -198,6 +194,6 @@ class BaseProcessor {
|
|
198 |
* @deprecated
|
199 |
*/
|
200 |
protected function prefix( $sSuffix = '', $sGlue = '-' ) {
|
201 |
-
return $this->
|
202 |
}
|
203 |
}
|
108 |
public function onModuleShutdown() {
|
109 |
}
|
110 |
|
|
|
|
|
111 |
public function init() {
|
112 |
}
|
113 |
|
173 |
return [];
|
174 |
}
|
175 |
|
|
|
|
|
176 |
public function deactivatePlugin() {
|
177 |
}
|
178 |
|
194 |
* @deprecated
|
195 |
*/
|
196 |
protected function prefix( $sSuffix = '', $sGlue = '-' ) {
|
197 |
+
return $this->getCon()->prefix( $sSuffix, $sGlue );
|
198 |
}
|
199 |
}
|
src/lib/src/Modules/Base/Options.php
CHANGED
@@ -56,8 +56,6 @@ class Options {
|
|
56 |
*/
|
57 |
protected $sPathToConfig;
|
58 |
|
59 |
-
/**
|
60 |
-
*/
|
61 |
public function __construct() {
|
62 |
}
|
63 |
|
@@ -146,8 +144,9 @@ class Options {
|
|
146 |
return array_filter(
|
147 |
$this->getOptionsKeys(),
|
148 |
function ( $sKey ) {
|
149 |
-
|
150 |
-
|
|
|
151 |
}
|
152 |
);
|
153 |
}
|
@@ -873,17 +872,6 @@ class Options {
|
|
873 |
return $this;
|
874 |
}
|
875 |
|
876 |
-
/**
|
877 |
-
* @param $sOptKey
|
878 |
-
* @param $mValue
|
879 |
-
* @return array|int|mixed|string
|
880 |
-
* @throws \Exception
|
881 |
-
* @deprecated 9.1.0
|
882 |
-
*/
|
883 |
-
private function ensureOptValueState( $sOptKey, $mValue ) {
|
884 |
-
return $mValue;
|
885 |
-
}
|
886 |
-
|
887 |
/**
|
888 |
* @param string $sOptKey
|
889 |
* @param mixed $mPotentialValue
|
56 |
*/
|
57 |
protected $sPathToConfig;
|
58 |
|
|
|
|
|
59 |
public function __construct() {
|
60 |
}
|
61 |
|
144 |
return array_filter(
|
145 |
$this->getOptionsKeys(),
|
146 |
function ( $sKey ) {
|
147 |
+
$opt = $this->getRawData_SingleOption( $sKey );
|
148 |
+
return !empty( $opt[ 'section' ] )
|
149 |
+
&& $opt[ 'section' ] !== 'section_non_ui';
|
150 |
}
|
151 |
);
|
152 |
}
|
872 |
return $this;
|
873 |
}
|
874 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
875 |
/**
|
876 |
* @param string $sOptKey
|
877 |
* @param mixed $mPotentialValue
|
src/lib/src/Modules/Base/ShieldUI.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class ShieldUI extends UI {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
public function getBaseDisplayData() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_BaseWpsf $mod */
|
15 |
+
$mod = $this->getMod();
|
16 |
+
|
17 |
+
return Services::DataManipulation()->mergeArraysRecursive(
|
18 |
+
parent::getBaseDisplayData(),
|
19 |
+
[
|
20 |
+
'head' => [
|
21 |
+
'html' => [
|
22 |
+
'lang' => Services::WpGeneral()->getLocale( '-' ),
|
23 |
+
'dir' => is_rtl() ? 'rtl' : 'ltr',
|
24 |
+
],
|
25 |
+
'meta' => [
|
26 |
+
[
|
27 |
+
'type' => 'http-equiv',
|
28 |
+
'type_type' => 'Cache-Control',
|
29 |
+
'content' => 'no-store, no-cache',
|
30 |
+
],
|
31 |
+
[
|
32 |
+
'type' => 'http-equiv',
|
33 |
+
'type_type' => 'Expires',
|
34 |
+
'content' => '0',
|
35 |
+
],
|
36 |
+
],
|
37 |
+
'scripts' => []
|
38 |
+
],
|
39 |
+
'ajax' => [
|
40 |
+
'sec_admin_login' => $mod->getSecAdminLoginAjaxData(),
|
41 |
+
],
|
42 |
+
'flags' => [
|
43 |
+
'show_promo' => !$this->getCon()->isPremiumActive(),
|
44 |
+
'has_session' => $mod->hasSession()
|
45 |
+
],
|
46 |
+
'hrefs' => [
|
47 |
+
'aar_forget_key' => $mod->isWlEnabled() ?
|
48 |
+
$this->getCon()->getLabels()[ 'AuthorURI' ] : 'https://shsec.io/gc'
|
49 |
+
],
|
50 |
+
'classes' => [
|
51 |
+
'top_container' => implode( ' ', array_filter( [
|
52 |
+
'odp-outercontainer',
|
53 |
+
$this->getCon()->isPremiumActive() ? 'is-pro' : 'is-not-pro',
|
54 |
+
$mod->getModSlug(),
|
55 |
+
Services::Request()->query( 'inav', '' )
|
56 |
+
] ) )
|
57 |
+
],
|
58 |
+
]
|
59 |
+
);
|
60 |
+
}
|
61 |
+
}
|
src/lib/src/Modules/Base/Strings.php
CHANGED
@@ -13,7 +13,7 @@ class Strings {
|
|
13 |
* @return string[]
|
14 |
*/
|
15 |
public function getDisplayStrings() {
|
16 |
-
$
|
17 |
|
18 |
$aProFeatures = [
|
19 |
__( 'Customer Support', 'wp-simple-firewall' ),
|
@@ -50,8 +50,8 @@ class Strings {
|
|
50 |
'logged_in' => __( 'Logged-In', 'wp-simple-firewall' ),
|
51 |
'username' => __( 'Username' ),
|
52 |
'blog' => __( 'Blog', 'wp-simple-firewall' ),
|
53 |
-
'save_all_settings' => sprintf( __( 'Save %s Settings', 'wp-simple-firewall' ), $
|
54 |
-
'plugin_name' => $
|
55 |
'options_title' => __( 'Options', 'wp-simple-firewall' ),
|
56 |
'options_summary' => __( 'Configure Module', 'wp-simple-firewall' ),
|
57 |
'actions_title' => __( 'Actions and Info', 'wp-simple-firewall' ),
|
@@ -135,12 +135,12 @@ class Strings {
|
|
135 |
}
|
136 |
|
137 |
/**
|
138 |
-
* @param string $
|
139 |
* @return array
|
140 |
* @throws \Exception
|
141 |
*/
|
142 |
-
public function getOptionStrings( $
|
143 |
-
$aOpt = $this->getOptions()->getOptDefinition( $
|
144 |
if ( is_array( $aOpt ) && !empty( $aOpt[ 'name' ] ) && !empty( $aOpt[ 'summary' ] ) && !empty( $aOpt[ 'description' ] ) ) {
|
145 |
return [
|
146 |
'name' => __( $aOpt[ 'name' ], 'wp-simple-firewall' ),
|
@@ -148,17 +148,17 @@ class Strings {
|
|
148 |
'description' => __( $aOpt[ 'description' ], 'wp-simple-firewall' ),
|
149 |
];
|
150 |
}
|
151 |
-
throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
-
* @param string $
|
156 |
* @return array
|
157 |
* @throws \Exception
|
158 |
*/
|
159 |
-
public function getSectionStrings( $
|
160 |
|
161 |
-
switch ( $
|
162 |
|
163 |
case 'section_user_messages' :
|
164 |
$sTitle = __( 'User Messages', 'wp-simple-firewall' );
|
@@ -171,14 +171,14 @@ class Strings {
|
|
171 |
break;
|
172 |
|
173 |
default:
|
174 |
-
$aSect = $this->getOptions()->getSection( $
|
175 |
if ( is_array( $aSect ) && !empty( $aSect[ 'title' ] ) && !empty( $aSect[ 'title_short' ] ) ) {
|
176 |
$sTitle = __( $aSect[ 'title' ], 'wp-simple-firewall' );
|
177 |
$sTitleShort = __( $aSect[ 'title_short' ], 'wp-simple-firewall' );
|
178 |
$aSummary = empty( $aSect[ 'summary' ] ) ? [] : $aSect[ 'summary' ];
|
179 |
}
|
180 |
else {
|
181 |
-
throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $
|
182 |
}
|
183 |
}
|
184 |
|
13 |
* @return string[]
|
14 |
*/
|
15 |
public function getDisplayStrings() {
|
16 |
+
$con = $this->getCon();
|
17 |
|
18 |
$aProFeatures = [
|
19 |
__( 'Customer Support', 'wp-simple-firewall' ),
|
50 |
'logged_in' => __( 'Logged-In', 'wp-simple-firewall' ),
|
51 |
'username' => __( 'Username' ),
|
52 |
'blog' => __( 'Blog', 'wp-simple-firewall' ),
|
53 |
+
'save_all_settings' => sprintf( __( 'Save %s Settings', 'wp-simple-firewall' ), $con->getHumanName() ),
|
54 |
+
'plugin_name' => $con->getHumanName(),
|
55 |
'options_title' => __( 'Options', 'wp-simple-firewall' ),
|
56 |
'options_summary' => __( 'Configure Module', 'wp-simple-firewall' ),
|
57 |
'actions_title' => __( 'Actions and Info', 'wp-simple-firewall' ),
|
135 |
}
|
136 |
|
137 |
/**
|
138 |
+
* @param string $key
|
139 |
* @return array
|
140 |
* @throws \Exception
|
141 |
*/
|
142 |
+
public function getOptionStrings( $key ) {
|
143 |
+
$aOpt = $this->getOptions()->getOptDefinition( $key );
|
144 |
if ( is_array( $aOpt ) && !empty( $aOpt[ 'name' ] ) && !empty( $aOpt[ 'summary' ] ) && !empty( $aOpt[ 'description' ] ) ) {
|
145 |
return [
|
146 |
'name' => __( $aOpt[ 'name' ], 'wp-simple-firewall' ),
|
148 |
'description' => __( $aOpt[ 'description' ], 'wp-simple-firewall' ),
|
149 |
];
|
150 |
}
|
151 |
+
throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $key ) );
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
+
* @param string $section
|
156 |
* @return array
|
157 |
* @throws \Exception
|
158 |
*/
|
159 |
+
public function getSectionStrings( $section ) {
|
160 |
|
161 |
+
switch ( $section ) {
|
162 |
|
163 |
case 'section_user_messages' :
|
164 |
$sTitle = __( 'User Messages', 'wp-simple-firewall' );
|
171 |
break;
|
172 |
|
173 |
default:
|
174 |
+
$aSect = $this->getOptions()->getSection( $section );
|
175 |
if ( is_array( $aSect ) && !empty( $aSect[ 'title' ] ) && !empty( $aSect[ 'title_short' ] ) ) {
|
176 |
$sTitle = __( $aSect[ 'title' ], 'wp-simple-firewall' );
|
177 |
$sTitleShort = __( $aSect[ 'title_short' ], 'wp-simple-firewall' );
|
178 |
$aSummary = empty( $aSect[ 'summary' ] ) ? [] : $aSect[ 'summary' ];
|
179 |
}
|
180 |
else {
|
181 |
+
throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $section ) );
|
182 |
}
|
183 |
}
|
184 |
|
src/lib/src/Modules/Base/UI.php
ADDED
@@ -0,0 +1,364 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class UI {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Will initiate the plugin options structure for use by the UI builder.
|
15 |
+
* It doesn't set any values, just populates the array created in buildOptions()
|
16 |
+
* with values stored.
|
17 |
+
* It has to handle the conversion of stored values to data to be displayed to the user.
|
18 |
+
*/
|
19 |
+
public function buildOptions() {
|
20 |
+
|
21 |
+
$bPremiumEnabled = $this->getCon()->isPremiumExtensionsEnabled();
|
22 |
+
|
23 |
+
$opts = $this->getOptions();
|
24 |
+
$aOptions = $opts->getOptionsForPluginUse();
|
25 |
+
|
26 |
+
foreach ( $aOptions as $nSectionKey => $aSection ) {
|
27 |
+
|
28 |
+
if ( !empty( $aSection[ 'options' ] ) ) {
|
29 |
+
|
30 |
+
foreach ( $aSection[ 'options' ] as $nKey => $aOption ) {
|
31 |
+
$aOption[ 'is_value_default' ] = ( $aOption[ 'value' ] === $aOption[ 'default' ] );
|
32 |
+
$bIsPrem = isset( $aOption[ 'premium' ] ) && $aOption[ 'premium' ];
|
33 |
+
if ( !$bIsPrem || $bPremiumEnabled ) {
|
34 |
+
$aSection[ 'options' ][ $nKey ] = $this->buildOptionForUi( $aOption );
|
35 |
+
}
|
36 |
+
else {
|
37 |
+
unset( $aSection[ 'options' ][ $nKey ] );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
if ( empty( $aSection[ 'options' ] ) ) {
|
42 |
+
unset( $aOptions[ $nSectionKey ] );
|
43 |
+
}
|
44 |
+
else {
|
45 |
+
try {
|
46 |
+
$aSection = array_merge(
|
47 |
+
$aSection,
|
48 |
+
$this->getMod()
|
49 |
+
->getStrings()
|
50 |
+
->getSectionStrings( $aSection[ 'slug' ] )
|
51 |
+
);
|
52 |
+
}
|
53 |
+
catch ( \Exception $oE ) {
|
54 |
+
}
|
55 |
+
$aOptions[ $nSectionKey ] = $aSection;
|
56 |
+
}
|
57 |
+
|
58 |
+
$aWarnings = [];
|
59 |
+
if ( !$opts->isSectionReqsMet( $aSection[ 'slug' ] ) ) {
|
60 |
+
$aWarnings[] = __( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.', 'wp-simple-firewall' );
|
61 |
+
}
|
62 |
+
$aOptions[ $nSectionKey ][ 'warnings' ] = array_merge(
|
63 |
+
$aWarnings,
|
64 |
+
$this->getSectionWarnings( $aSection[ 'slug' ] )
|
65 |
+
);
|
66 |
+
$aOptions[ $nSectionKey ][ 'notices' ] = $this->getSectionNotices( $aSection[ 'slug' ] );
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
return $aOptions;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @param array $aOptParams
|
75 |
+
* @return array
|
76 |
+
*/
|
77 |
+
protected function buildOptionForUi( $aOptParams ) {
|
78 |
+
|
79 |
+
$mCurrent = $aOptParams[ 'value' ];
|
80 |
+
|
81 |
+
switch ( $aOptParams[ 'type' ] ) {
|
82 |
+
|
83 |
+
case 'password':
|
84 |
+
if ( !empty( $mCurrent ) ) {
|
85 |
+
$mCurrent = '';
|
86 |
+
}
|
87 |
+
break;
|
88 |
+
|
89 |
+
case 'array':
|
90 |
+
|
91 |
+
if ( empty( $mCurrent ) || !is_array( $mCurrent ) ) {
|
92 |
+
$mCurrent = [];
|
93 |
+
}
|
94 |
+
|
95 |
+
$aOptParams[ 'rows' ] = count( $mCurrent ) + 2;
|
96 |
+
$mCurrent = stripslashes( implode( "\n", $mCurrent ) );
|
97 |
+
|
98 |
+
break;
|
99 |
+
|
100 |
+
case 'comma_separated_lists':
|
101 |
+
|
102 |
+
$aNewValues = [];
|
103 |
+
if ( !empty( $mCurrent ) && is_array( $mCurrent ) ) {
|
104 |
+
|
105 |
+
foreach ( $mCurrent as $sPage => $aParams ) {
|
106 |
+
$aNewValues[] = $sPage.', '.implode( ", ", $aParams );
|
107 |
+
}
|
108 |
+
}
|
109 |
+
$aOptParams[ 'rows' ] = count( $aNewValues ) + 1;
|
110 |
+
$mCurrent = implode( "\n", $aNewValues );
|
111 |
+
|
112 |
+
break;
|
113 |
+
|
114 |
+
case 'multiple_select':
|
115 |
+
if ( !is_array( $mCurrent ) ) {
|
116 |
+
$mCurrent = [];
|
117 |
+
}
|
118 |
+
break;
|
119 |
+
|
120 |
+
case 'text':
|
121 |
+
$mCurrent = stripslashes( $this->getMod()->getTextOpt( $aOptParams[ 'key' ] ) );
|
122 |
+
break;
|
123 |
+
}
|
124 |
+
|
125 |
+
$aParams = [
|
126 |
+
'value' => is_scalar( $mCurrent ) ? esc_attr( $mCurrent ) : $mCurrent,
|
127 |
+
'disabled' => !$this->getCon()
|
128 |
+
->isPremiumActive() && ( isset( $aOptParams[ 'premium' ] ) && $aOptParams[ 'premium' ] ),
|
129 |
+
];
|
130 |
+
$aParams[ 'enabled' ] = !$aParams[ 'disabled' ];
|
131 |
+
$aOptParams = array_merge( [ 'rows' => 2 ], $aOptParams, $aParams );
|
132 |
+
|
133 |
+
// add strings
|
134 |
+
try {
|
135 |
+
$aOptStrings = $this->getMod()->getStrings()->getOptionStrings( $aOptParams[ 'key' ] );
|
136 |
+
if ( !is_array( $aOptStrings[ 'description' ] ) ) {
|
137 |
+
$aOptStrings[ 'description' ] = [ $aOptStrings[ 'description' ] ];
|
138 |
+
}
|
139 |
+
$aOptParams = Services::DataManipulation()->mergeArraysRecursive( $aOptParams, $aOptStrings );
|
140 |
+
}
|
141 |
+
catch ( \Exception $oE ) {
|
142 |
+
}
|
143 |
+
return $aOptParams;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @return array
|
148 |
+
*/
|
149 |
+
public function getBaseDisplayData() {
|
150 |
+
$mod = $this->getMod();
|
151 |
+
$con = $this->getCon();
|
152 |
+
|
153 |
+
/** @var Shield\Modules\Plugin\Options $oPluginOptions */
|
154 |
+
$oPluginOptions = $con->getModule_Plugin()->getOptions();
|
155 |
+
|
156 |
+
return [
|
157 |
+
'sPluginName' => $con->getHumanName(),
|
158 |
+
'sTagline' => $this->getOptions()->getFeatureTagline(),
|
159 |
+
'nonce_field' => wp_nonce_field( $con->getPluginPrefix(), '_wpnonce', true, false ), //don't echo!
|
160 |
+
'form_action' => 'admin.php?page='.$mod->getModSlug(),
|
161 |
+
'aPluginLabels' => $con->getLabels(),
|
162 |
+
'help_video' => [
|
163 |
+
'auto_show' => $this->getIfAutoShowHelpVideo(),
|
164 |
+
'display_id' => 'ShieldHelpVideo'.$mod->getSlug(),
|
165 |
+
'options' => $this->getHelpVideoOptions(),
|
166 |
+
'displayable' => $this->isHelpVideoDisplayable(),
|
167 |
+
'show' => $this->isHelpVideoDisplayable() && !$this->getHelpVideoHasBeenClosed(),
|
168 |
+
'width' => 772,
|
169 |
+
'height' => 454,
|
170 |
+
],
|
171 |
+
|
172 |
+
'aSummaryData' => array_filter(
|
173 |
+
$mod->getModulesSummaryData(),
|
174 |
+
function ( $summary ) {
|
175 |
+
return $summary[ 'show_mod_opts' ];
|
176 |
+
}
|
177 |
+
),
|
178 |
+
|
179 |
+
'sPageTitle' => $mod->getMainFeatureName(),
|
180 |
+
'data' => [
|
181 |
+
'mod_slug' => $mod->getModSlug( true ),
|
182 |
+
'mod_slug_short' => $mod->getModSlug( false ),
|
183 |
+
'all_options' => $this->buildOptions(),
|
184 |
+
'xferable_opts' => ( new Shield\Modules\Plugin\Lib\ImportExport\Options\BuildTransferableOptions() )
|
185 |
+
->setMod( $mod )
|
186 |
+
->build(),
|
187 |
+
'hidden_options' => $this->getOptions()->getHiddenOptions()
|
188 |
+
],
|
189 |
+
'ajax' => [
|
190 |
+
'mod_options' => $mod->getAjaxActionData( 'mod_options' ),
|
191 |
+
],
|
192 |
+
'vendors' => [
|
193 |
+
'widget_freshdesk' => '3000000081' /* TODO: plugin spec config */
|
194 |
+
],
|
195 |
+
'strings' => $mod->getStrings()->getDisplayStrings(),
|
196 |
+
'flags' => [
|
197 |
+
'access_restricted' => !$mod->canDisplayOptionsForm(),
|
198 |
+
'show_ads' => $mod->getIsShowMarketing(),
|
199 |
+
'wrap_page_content' => true,
|
200 |
+
'show_standard_options' => true,
|
201 |
+
'show_content_help' => true,
|
202 |
+
'show_alt_content' => false,
|
203 |
+
'has_wizard' => $mod->hasWizard(),
|
204 |
+
'is_premium' => $con->isPremiumActive(),
|
205 |
+
'show_transfer_switch' => $con->isPremiumActive(),
|
206 |
+
'is_wpcli' => $oPluginOptions->isEnabledWpcli()
|
207 |
+
],
|
208 |
+
'hrefs' => [
|
209 |
+
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
210 |
+
'goprofooter' => 'https://shsec.io/goprofooter',
|
211 |
+
'wizard_link' => $mod->getUrl_WizardLanding(),
|
212 |
+
'wizard_landing' => $mod->getUrl_WizardLanding(),
|
213 |
+
|
214 |
+
'form_action' => Services::Request()->getUri(),
|
215 |
+
'css_bootstrap' => $con->getPluginUrl_Css( 'bootstrap4.min' ),
|
216 |
+
'css_pages' => $con->getPluginUrl_Css( 'pages' ),
|
217 |
+
'css_steps' => $con->getPluginUrl_Css( 'jquery.steps' ),
|
218 |
+
'css_fancybox' => $con->getPluginUrl_Css( 'jquery.fancybox.min' ),
|
219 |
+
'css_globalplugin' => $con->getPluginUrl_Css( 'global-plugin' ),
|
220 |
+
'css_wizard' => $con->getPluginUrl_Css( 'wizard' ),
|
221 |
+
'js_jquery' => Services::Includes()->getUrl_Jquery(),
|
222 |
+
'js_bootstrap' => $con->getPluginUrl_Js( 'bootstrap4.bundle.min' ),
|
223 |
+
'js_fancybox' => $con->getPluginUrl_Js( 'jquery.fancybox.min' ),
|
224 |
+
'js_globalplugin' => $con->getPluginUrl_Js( 'global-plugin' ),
|
225 |
+
'js_steps' => $con->getPluginUrl_Js( 'jquery.steps.min' ),
|
226 |
+
'js_wizard' => $con->getPluginUrl_Js( 'wizard' ),
|
227 |
+
],
|
228 |
+
'imgs' => [
|
229 |
+
'favicon' => $con->getPluginUrl_Image( 'pluginlogo_24x24.png' ),
|
230 |
+
'plugin_banner' => $con->getPluginUrl_Image( 'banner-1500x500-transparent.png' ),
|
231 |
+
],
|
232 |
+
'content' => [
|
233 |
+
'options_form' => '',
|
234 |
+
'alt' => '',
|
235 |
+
'actions' => '',
|
236 |
+
'help' => '',
|
237 |
+
'wizard_landing' => ''
|
238 |
+
]
|
239 |
+
];
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* @return array
|
244 |
+
*/
|
245 |
+
public function getInsightsConfigCardData() {
|
246 |
+
return [];
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* @return array
|
251 |
+
*/
|
252 |
+
public function getInsightsNoticesData() {
|
253 |
+
return [];
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* @return array
|
258 |
+
*/
|
259 |
+
protected function getModDisabledInsight() {
|
260 |
+
$mod = $this->getMod();
|
261 |
+
return [
|
262 |
+
'name' => __( 'Module Disabled', 'wp-simple-firewall' ),
|
263 |
+
'enabled' => false,
|
264 |
+
'summary' => __( 'All features of this module are completely disabled', 'wp-simple-firewall' ),
|
265 |
+
'weight' => 2,
|
266 |
+
'href' => $mod->getUrl_DirectLinkToOption( $mod->getEnableModOptKey() ),
|
267 |
+
];
|
268 |
+
}
|
269 |
+
|
270 |
+
protected function getHelpVideoOptions() {
|
271 |
+
$aOptions = $this->getOptions()->getOpt( 'help_video_options', [] );
|
272 |
+
if ( is_null( $aOptions ) || !is_array( $aOptions ) ) {
|
273 |
+
$aOptions = [
|
274 |
+
'closed' => false,
|
275 |
+
'displayed' => false,
|
276 |
+
'played' => false,
|
277 |
+
];
|
278 |
+
$this->getOptions()->setOpt( 'help_video_options', $aOptions );
|
279 |
+
}
|
280 |
+
return $aOptions;
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* @param string $sId
|
285 |
+
* @return string
|
286 |
+
*/
|
287 |
+
protected function getHelpVideoUrl( $sId ) {
|
288 |
+
return sprintf( 'https://player.vimeo.com/video/%s', $sId );
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* @return bool
|
293 |
+
*/
|
294 |
+
protected function getIfAutoShowHelpVideo() {
|
295 |
+
return !$this->getHelpVideoHasBeenClosed();
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* @return bool
|
300 |
+
*/
|
301 |
+
protected function getHelpVideoHasBeenDisplayed() {
|
302 |
+
return (bool)$this->getHelpVideoOption( 'displayed' );
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* @return bool
|
307 |
+
*/
|
308 |
+
protected function getVideoHasBeenPlayed() {
|
309 |
+
return (bool)$this->getHelpVideoOption( 'played' );
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* @param string $sKey
|
314 |
+
* @return mixed|null
|
315 |
+
*/
|
316 |
+
protected function getHelpVideoOption( $sKey ) {
|
317 |
+
$aOpts = $this->getHelpVideoOptions();
|
318 |
+
return isset( $aOpts[ $sKey ] ) ? $aOpts[ $sKey ] : null;
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* @return bool
|
323 |
+
*/
|
324 |
+
protected function getHelpVideoHasBeenClosed() {
|
325 |
+
return (bool)$this->getHelpVideoOption( 'closed' );
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* @return bool
|
330 |
+
*/
|
331 |
+
protected function isHelpVideoDisplayable() {
|
332 |
+
return false;
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* @return string
|
337 |
+
*/
|
338 |
+
protected function getHelpVideoId() {
|
339 |
+
return $this->getOptions()->getDef( 'help_video_id' );
|
340 |
+
}
|
341 |
+
|
342 |
+
/**
|
343 |
+
* @param string $section
|
344 |
+
* @return array
|
345 |
+
*/
|
346 |
+
protected function getSectionNotices( $section ) {
|
347 |
+
return [];
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* @param string $section
|
352 |
+
* @return array
|
353 |
+
*/
|
354 |
+
protected function getSectionWarnings( $section ) {
|
355 |
+
return [];
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* @return bool
|
360 |
+
*/
|
361 |
+
public function isEnabledForUiSummary() {
|
362 |
+
return $this->getMod()->isModuleEnabled();
|
363 |
+
}
|
364 |
+
}
|
src/lib/src/Modules/BaseShield/ShieldProcessor.php
CHANGED
@@ -19,8 +19,8 @@ class ShieldProcessor extends Base\BaseProcessor {
|
|
19 |
*/
|
20 |
public function init() {
|
21 |
parent::init();
|
22 |
-
$
|
23 |
-
add_filter( $
|
24 |
}
|
25 |
|
26 |
/**
|
19 |
*/
|
20 |
public function init() {
|
21 |
parent::init();
|
22 |
+
$con = $this->getCon();
|
23 |
+
add_filter( $con->prefix( 'collect_tracking_data' ), [ $this, 'tracking_DataCollect' ] );
|
24 |
}
|
25 |
|
26 |
/**
|
src/lib/src/Modules/CommentsFilter/AdminNotices.php
CHANGED
@@ -50,16 +50,18 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
50 |
* @return bool
|
51 |
*/
|
52 |
protected function isDisplayNeeded( $oNotice ) {
|
53 |
-
/** @var
|
54 |
-
$
|
55 |
|
56 |
switch ( $oNotice->id ) {
|
57 |
|
58 |
case 'akismet-running':
|
59 |
$oWpPlugins = Services::WpPlugins();
|
60 |
$sPluginFile = $oWpPlugins->findPluginFileFromDirName( 'akismet' );
|
61 |
-
$bNeeded = $
|
62 |
-
&& !empty( $sPluginFile )
|
|
|
|
|
63 |
break;
|
64 |
|
65 |
default:
|
50 |
* @return bool
|
51 |
*/
|
52 |
protected function isDisplayNeeded( $oNotice ) {
|
53 |
+
/** @var Options $opts */
|
54 |
+
$opts = $this->getOptions();
|
55 |
|
56 |
switch ( $oNotice->id ) {
|
57 |
|
58 |
case 'akismet-running':
|
59 |
$oWpPlugins = Services::WpPlugins();
|
60 |
$sPluginFile = $oWpPlugins->findPluginFileFromDirName( 'akismet' );
|
61 |
+
$bNeeded = $this->getMod()->isModuleEnabled()
|
62 |
+
&& !empty( $sPluginFile )
|
63 |
+
&& $oWpPlugins->isActive( $sPluginFile )
|
64 |
+
&& $opts->isEnabledHumanCheck();
|
65 |
break;
|
66 |
|
67 |
default:
|
src/lib/src/Modules/CommentsFilter/AjaxHandler.php
CHANGED
@@ -8,18 +8,18 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
-
* @param string $
|
12 |
* @return array
|
13 |
*/
|
14 |
-
protected function processAjaxAction( $
|
15 |
|
16 |
-
switch ( $
|
17 |
case 'comment_token'.Services::IP()->getRequestIp():
|
18 |
$aResponse = $this->ajaxExec_GenCommentToken();
|
19 |
break;
|
20 |
|
21 |
default:
|
22 |
-
$aResponse = parent::processAjaxAction( $
|
23 |
}
|
24 |
|
25 |
return $aResponse;
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
+
* @param string $action
|
12 |
* @return array
|
13 |
*/
|
14 |
+
protected function processAjaxAction( $action ) {
|
15 |
|
16 |
+
switch ( $action ) {
|
17 |
case 'comment_token'.Services::IP()->getRequestIp():
|
18 |
$aResponse = $this->ajaxExec_GenCommentToken();
|
19 |
break;
|
20 |
|
21 |
default:
|
22 |
+
$aResponse = parent::processAjaxAction( $action );
|
23 |
}
|
24 |
|
25 |
return $aResponse;
|
src/lib/src/Modules/CommentsFilter/Options.php
CHANGED
@@ -6,6 +6,13 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
6 |
|
7 |
class Options extends Base\ShieldOptions {
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
/**
|
10 |
* @return string[]
|
11 |
*/
|
@@ -44,4 +51,38 @@ class Options extends Base\ShieldOptions {
|
|
44 |
)
|
45 |
);
|
46 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
}
|
6 |
|
7 |
class Options extends Base\ShieldOptions {
|
8 |
|
9 |
+
/**
|
10 |
+
* @return int
|
11 |
+
*/
|
12 |
+
public function getApprovedMinimum() {
|
13 |
+
return (int)$this->getOpt( 'trusted_commenter_minimum', 1 );
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* @return string[]
|
18 |
*/
|
51 |
)
|
52 |
);
|
53 |
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return string[]
|
57 |
+
*/
|
58 |
+
public function getTrustedRoles() {
|
59 |
+
$aRoles = [];
|
60 |
+
if ( $this->isPremium() ) {
|
61 |
+
$aRoles = $this->getOpt( 'trusted_user_roles', [] );
|
62 |
+
}
|
63 |
+
return is_array( $aRoles ) ? $aRoles : [];
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @return bool
|
68 |
+
*/
|
69 |
+
public function isEnabledGaspCheck() {
|
70 |
+
return $this->isOpt( 'enable_comments_gasp_protection', 'Y' )
|
71 |
+
&& ( $this->getTokenExpireInterval() > $this->getTokenCooldown() );
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return bool
|
76 |
+
*/
|
77 |
+
public function isEnabledCaptcha() {
|
78 |
+
return !$this->isOpt( 'google_recaptcha_style_comments', 'disabled' );
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return bool
|
83 |
+
*/
|
84 |
+
public function isEnabledHumanCheck() {
|
85 |
+
return $this->isOpt( 'enable_comments_human_spam_filter', 'Y' )
|
86 |
+
&& count( $this->getHumanSpamFilterItems() ) > 0;
|
87 |
+
}
|
88 |
}
|
src/lib/src/Modules/CommentsFilter/Scan/Bot.php
CHANGED
@@ -64,12 +64,12 @@ class Bot {
|
|
64 |
* @return bool
|
65 |
*/
|
66 |
private function checkTokenHash( $sToken, $nTs, $nPostId ) {
|
67 |
-
$
|
68 |
-
$
|
69 |
'comtok-'.md5( sprintf( '%s-%s-%s', $nPostId, $nTs, Services::IP()->getRequestIp() ) )
|
70 |
);
|
71 |
-
$sStoredToken = Services::WpGeneral()->getTransient( $
|
72 |
-
$
|
73 |
return hash_equals(
|
74 |
(string)$sStoredToken,
|
75 |
$sToken
|
64 |
* @return bool
|
65 |
*/
|
66 |
private function checkTokenHash( $sToken, $nTs, $nPostId ) {
|
67 |
+
$WP = Services::WpGeneral();
|
68 |
+
$key = $this->getCon()->prefix(
|
69 |
'comtok-'.md5( sprintf( '%s-%s-%s', $nPostId, $nTs, Services::IP()->getRequestIp() ) )
|
70 |
);
|
71 |
+
$sStoredToken = Services::WpGeneral()->getTransient( $key );
|
72 |
+
$WP->deleteTransient( $key ); // single use hashes & clean as we go
|
73 |
return hash_equals(
|
74 |
(string)$sStoredToken,
|
75 |
$sToken
|
src/lib/src/Modules/CommentsFilter/Scan/Scanner.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Scan;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Utilities;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -113,31 +114,33 @@ class Scanner {
|
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
-
* @param $aCommData
|
117 |
* @return true|\WP_Error|null
|
118 |
*/
|
119 |
private function runScans( $aCommData ) {
|
120 |
-
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $
|
121 |
-
$
|
|
|
|
|
122 |
|
123 |
$mResult = true;
|
124 |
|
125 |
-
if ( !is_wp_error( $mResult ) && $
|
126 |
$mResult = ( new Bot() )
|
127 |
-
->setMod( $
|
128 |
->scan( $aCommData[ 'comment_post_ID' ] );
|
129 |
}
|
130 |
|
131 |
-
if ( !is_wp_error( $mResult ) && $
|
132 |
try {
|
133 |
-
if ( $
|
134 |
( new Utilities\HCaptcha\TestRequest() )
|
135 |
-
->setMod( $
|
136 |
->test();
|
137 |
}
|
138 |
else {
|
139 |
( new Utilities\ReCaptcha\TestRequest() )
|
140 |
-
->setMod( $
|
141 |
->test();
|
142 |
}
|
143 |
}
|
@@ -146,9 +149,9 @@ class Scanner {
|
|
146 |
}
|
147 |
}
|
148 |
|
149 |
-
if ( !is_wp_error( $mResult ) && $
|
150 |
$mResult = ( new Human() )
|
151 |
-
->setMod( $
|
152 |
->scan( $aCommData );
|
153 |
}
|
154 |
|
@@ -161,10 +164,11 @@ class Scanner {
|
|
161 |
* @return bool
|
162 |
*/
|
163 |
public function getIfDoCommentsCheck( $nPostId, $sCommentEmail ) {
|
164 |
-
/** @var
|
165 |
-
$
|
166 |
-
$
|
167 |
-
return
|
168 |
-
&&
|
|
|
169 |
}
|
170 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Scan;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Options;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Utilities;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
+
* @param array $aCommData
|
118 |
* @return true|\WP_Error|null
|
119 |
*/
|
120 |
private function runScans( $aCommData ) {
|
121 |
+
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $mod */
|
122 |
+
$mod = $this->getMod();
|
123 |
+
/** @var Options $opts */
|
124 |
+
$opts = $this->getOptions();
|
125 |
|
126 |
$mResult = true;
|
127 |
|
128 |
+
if ( !is_wp_error( $mResult ) && $opts->isEnabledGaspCheck() ) {
|
129 |
$mResult = ( new Bot() )
|
130 |
+
->setMod( $this->getMod() )
|
131 |
->scan( $aCommData[ 'comment_post_ID' ] );
|
132 |
}
|
133 |
|
134 |
+
if ( !is_wp_error( $mResult ) && $opts->isEnabledCaptcha() && $mod->getCaptchaCfg()->ready ) {
|
135 |
try {
|
136 |
+
if ( $mod->getCaptchaCfg()->provider === 'hcaptcha' ) {
|
137 |
( new Utilities\HCaptcha\TestRequest() )
|
138 |
+
->setMod( $this->getMod() )
|
139 |
->test();
|
140 |
}
|
141 |
else {
|
142 |
( new Utilities\ReCaptcha\TestRequest() )
|
143 |
+
->setMod( $this->getMod() )
|
144 |
->test();
|
145 |
}
|
146 |
}
|
149 |
}
|
150 |
}
|
151 |
|
152 |
+
if ( !is_wp_error( $mResult ) && $opts->isEnabledHumanCheck() ) {
|
153 |
$mResult = ( new Human() )
|
154 |
+
->setMod( $this->getMod() )
|
155 |
->scan( $aCommData );
|
156 |
}
|
157 |
|
164 |
* @return bool
|
165 |
*/
|
166 |
public function getIfDoCommentsCheck( $nPostId, $sCommentEmail ) {
|
167 |
+
/** @var Options $opts */
|
168 |
+
$opts = $this->getOptions();
|
169 |
+
$post = Services::WpPost()->getById( $nPostId );
|
170 |
+
return $post instanceof \WP_Post
|
171 |
+
&& Services::WpComments()->isCommentsOpen( $post )
|
172 |
+
&& !( new IsEmailTrusted() )->trusted( $sCommentEmail, $opts->getApprovedMinimum(), $opts->getTrustedRoles() );
|
173 |
}
|
174 |
}
|
src/lib/src/Modules/CommentsFilter/Strings.php
CHANGED
@@ -26,13 +26,13 @@ class Strings extends Base\Strings {
|
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
-
* @param string $
|
30 |
* @return array
|
31 |
* @throws \Exception
|
32 |
*/
|
33 |
-
public function getSectionStrings( $
|
34 |
|
35 |
-
switch ( $
|
36 |
|
37 |
case 'section_enable_plugin_feature_spam_comments_protection_filter' :
|
38 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -71,7 +71,7 @@ class Strings extends Base\Strings {
|
|
71 |
break;
|
72 |
|
73 |
default:
|
74 |
-
return parent::getSectionStrings( $
|
75 |
}
|
76 |
|
77 |
return [
|
@@ -82,16 +82,16 @@ class Strings extends Base\Strings {
|
|
82 |
}
|
83 |
|
84 |
/**
|
85 |
-
* @param string $
|
86 |
* @return array
|
87 |
* @throws \Exception
|
88 |
*/
|
89 |
-
public function getOptionStrings( $
|
90 |
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
91 |
$oMod = $this->getMod();
|
92 |
$sModName = $this->getMod()->getMainFeatureName();
|
93 |
|
94 |
-
switch ( $
|
95 |
|
96 |
case 'enable_comments_filter' :
|
97 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -186,7 +186,7 @@ class Strings extends Base\Strings {
|
|
186 |
break;
|
187 |
|
188 |
default:
|
189 |
-
return parent::getOptionStrings( $
|
190 |
}
|
191 |
|
192 |
return [
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
+
* @param string $section
|
30 |
* @return array
|
31 |
* @throws \Exception
|
32 |
*/
|
33 |
+
public function getSectionStrings( $section ) {
|
34 |
|
35 |
+
switch ( $section ) {
|
36 |
|
37 |
case 'section_enable_plugin_feature_spam_comments_protection_filter' :
|
38 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
71 |
break;
|
72 |
|
73 |
default:
|
74 |
+
return parent::getSectionStrings( $section );
|
75 |
}
|
76 |
|
77 |
return [
|
82 |
}
|
83 |
|
84 |
/**
|
85 |
+
* @param string $key
|
86 |
* @return array
|
87 |
* @throws \Exception
|
88 |
*/
|
89 |
+
public function getOptionStrings( $key ) {
|
90 |
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
91 |
$oMod = $this->getMod();
|
92 |
$sModName = $this->getMod()->getMainFeatureName();
|
93 |
|
94 |
+
switch ( $key ) {
|
95 |
|
96 |
case 'enable_comments_filter' :
|
97 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
186 |
break;
|
187 |
|
188 |
default:
|
189 |
+
return parent::getOptionStrings( $key );
|
190 |
}
|
191 |
|
192 |
return [
|
src/lib/src/Modules/CommentsFilter/UI.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
|
7 |
+
class UI extends Base\ShieldUI {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getInsightsConfigCardData() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $mod */
|
14 |
+
$mod = $this->getMod();
|
15 |
+
/** @var Options $opts */
|
16 |
+
$opts = $this->getOptions();
|
17 |
+
|
18 |
+
$data = [
|
19 |
+
'strings' => [
|
20 |
+
'title' => __( 'SPAM Blocking', 'wp-simple-firewall' ),
|
21 |
+
'sub' => __( 'Block Bot & Human Comment SPAM', 'wp-simple-firewall' ),
|
22 |
+
],
|
23 |
+
'key_opts' => [],
|
24 |
+
'href_options' => $mod->getUrl_AdminPage()
|
25 |
+
];
|
26 |
+
|
27 |
+
if ( !$mod->isModOptEnabled() ) {
|
28 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$data[ 'key_opts' ][ 'bot' ] = [
|
32 |
+
'name' => __( 'Bot SPAM', 'wp-simple-firewall' ),
|
33 |
+
'enabled' => $opts->isEnabledGaspCheck() || $mod->isEnabledCaptcha(),
|
34 |
+
'summary' => ( $opts->isEnabledGaspCheck() || $mod->isEnabledCaptcha() ) ?
|
35 |
+
__( 'Bot SPAM comments are blocked', 'wp-simple-firewall' )
|
36 |
+
: __( 'There is no protection against Bot SPAM comments', 'wp-simple-firewall' ),
|
37 |
+
'weight' => 2,
|
38 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_bot_comment_spam_protection_filter' ),
|
39 |
+
];
|
40 |
+
$data[ 'key_opts' ][ 'human' ] = [
|
41 |
+
'name' => __( 'Human SPAM', 'wp-simple-firewall' ),
|
42 |
+
'enabled' => $opts->isEnabledHumanCheck(),
|
43 |
+
'summary' => $opts->isEnabledHumanCheck() ?
|
44 |
+
__( 'Comments posted by humans are checked for SPAM', 'wp-simple-firewall' )
|
45 |
+
: __( "Comments posted by humans aren't checked for SPAM", 'wp-simple-firewall' ),
|
46 |
+
'weight' => 1,
|
47 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_human_spam_filter' ),
|
48 |
+
];
|
49 |
+
}
|
50 |
+
|
51 |
+
return $data;
|
52 |
+
}
|
53 |
+
}
|
src/lib/src/Modules/Events/AjaxHandler.php
CHANGED
@@ -9,12 +9,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
11 |
/**
|
12 |
-
* @param string $
|
13 |
* @return array
|
14 |
*/
|
15 |
-
protected function processAjaxAction( $
|
16 |
|
17 |
-
switch ( $
|
18 |
case 'render_chart':
|
19 |
$aResponse = $this->ajaxExec_RenderChart();
|
20 |
break;
|
@@ -24,7 +24,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
24 |
break;
|
25 |
|
26 |
default:
|
27 |
-
$aResponse = parent::processAjaxAction( $
|
28 |
}
|
29 |
|
30 |
return $aResponse;
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
11 |
/**
|
12 |
+
* @param string $action
|
13 |
* @return array
|
14 |
*/
|
15 |
+
protected function processAjaxAction( $action ) {
|
16 |
|
17 |
+
switch ( $action ) {
|
18 |
case 'render_chart':
|
19 |
$aResponse = $this->ajaxExec_RenderChart();
|
20 |
break;
|
24 |
break;
|
25 |
|
26 |
default:
|
27 |
+
$aResponse = parent::processAjaxAction( $action );
|
28 |
}
|
29 |
|
30 |
return $aResponse;
|
src/lib/src/Modules/Events/Options.php
CHANGED
@@ -8,6 +8,7 @@ class Options extends Base\ShieldOptions {
|
|
8 |
|
9 |
/**
|
10 |
* @return string[]
|
|
|
11 |
*/
|
12 |
public function getDbColumns_Events() {
|
13 |
return $this->getDef( 'events_table_columns' );
|
8 |
|
9 |
/**
|
10 |
* @return string[]
|
11 |
+
* @deprecated 9.2.0
|
12 |
*/
|
13 |
public function getDbColumns_Events() {
|
14 |
return $this->getDef( 'events_table_columns' );
|
src/lib/src/Modules/Firewall/Strings.php
CHANGED
@@ -7,13 +7,13 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
7 |
class Strings extends Base\Strings {
|
8 |
|
9 |
/**
|
10 |
-
* @param string $
|
11 |
* @return array
|
12 |
* @throws \Exception
|
13 |
*/
|
14 |
-
public function getSectionStrings( $
|
15 |
|
16 |
-
switch ( $
|
17 |
|
18 |
case 'section_enable_plugin_feature_wordpress_firewall' :
|
19 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -55,7 +55,7 @@ class Strings extends Base\Strings {
|
|
55 |
break;
|
56 |
|
57 |
default:
|
58 |
-
return parent::getSectionStrings( $
|
59 |
}
|
60 |
|
61 |
return [
|
@@ -66,15 +66,15 @@ class Strings extends Base\Strings {
|
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
-
* @param string $
|
70 |
* @return array
|
71 |
* @throws \Exception
|
72 |
*/
|
73 |
-
public function getOptionStrings( $
|
74 |
|
75 |
$sModName = $this->getMod()->getMainFeatureName();
|
76 |
|
77 |
-
switch ( $
|
78 |
|
79 |
case 'enable_firewall' :
|
80 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -169,7 +169,7 @@ class Strings extends Base\Strings {
|
|
169 |
break;
|
170 |
|
171 |
default:
|
172 |
-
return parent::getOptionStrings( $
|
173 |
}
|
174 |
|
175 |
return [
|
7 |
class Strings extends Base\Strings {
|
8 |
|
9 |
/**
|
10 |
+
* @param string $section
|
11 |
* @return array
|
12 |
* @throws \Exception
|
13 |
*/
|
14 |
+
public function getSectionStrings( $section ) {
|
15 |
|
16 |
+
switch ( $section ) {
|
17 |
|
18 |
case 'section_enable_plugin_feature_wordpress_firewall' :
|
19 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
55 |
break;
|
56 |
|
57 |
default:
|
58 |
+
return parent::getSectionStrings( $section );
|
59 |
}
|
60 |
|
61 |
return [
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
+
* @param string $key
|
70 |
* @return array
|
71 |
* @throws \Exception
|
72 |
*/
|
73 |
+
public function getOptionStrings( $key ) {
|
74 |
|
75 |
$sModName = $this->getMod()->getMainFeatureName();
|
76 |
|
77 |
+
switch ( $key ) {
|
78 |
|
79 |
case 'enable_firewall' :
|
80 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
169 |
break;
|
170 |
|
171 |
default:
|
172 |
+
return parent::getOptionStrings( $key );
|
173 |
}
|
174 |
|
175 |
return [
|
src/lib/src/Modules/Firewall/UI.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Firewall;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
|
7 |
+
class UI extends Base\ShieldUI {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getInsightsConfigCardData() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_Firewall $mod */
|
14 |
+
$mod = $this->getMod();
|
15 |
+
/** @var Options $opts */
|
16 |
+
$opts = $this->getOptions();
|
17 |
+
|
18 |
+
$data = [
|
19 |
+
'strings' => [
|
20 |
+
'title' => __( 'Firewall', 'wp-simple-firewall' ),
|
21 |
+
'sub' => __( 'Block Malicious Requests', 'wp-simple-firewall' ),
|
22 |
+
],
|
23 |
+
'key_opts' => [],
|
24 |
+
'href_options' => $mod->getUrl_AdminPage()
|
25 |
+
];
|
26 |
+
|
27 |
+
if ( !$mod->isModOptEnabled() ) {
|
28 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$data[ 'key_opts' ][ 'mod' ] = [
|
32 |
+
'name' => __( 'Firewall', 'wp-simple-firewall' ),
|
33 |
+
'enabled' => $mod->isModOptEnabled(),
|
34 |
+
'summary' => $mod->isModOptEnabled() ?
|
35 |
+
__( 'Your site is protected against malicious requests', 'wp-simple-firewall' )
|
36 |
+
: __( 'Your site is not protected against malicious requests', 'wp-simple-firewall' ),
|
37 |
+
'weight' => 2,
|
38 |
+
'href' => $mod->getUrl_DirectLinkToOption( $mod->getEnableModOptKey() ),
|
39 |
+
];
|
40 |
+
|
41 |
+
//ignoring admin isn't a good idea
|
42 |
+
$bAdminIncluded = !$opts->isIgnoreAdmin();
|
43 |
+
$data[ 'key_opts' ][ 'admin' ] = [
|
44 |
+
'name' => __( 'Ignore Admins', 'wp-simple-firewall' ),
|
45 |
+
'enabled' => $bAdminIncluded,
|
46 |
+
'summary' => $bAdminIncluded ?
|
47 |
+
__( "Firewall rules are also applied to admins", 'wp-simple-firewall' )
|
48 |
+
: __( "Firewall rules aren't applied to admins", 'wp-simple-firewall' ),
|
49 |
+
'weight' => 1,
|
50 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'whitelist_admins' ),
|
51 |
+
];
|
52 |
+
}
|
53 |
+
|
54 |
+
return $data;
|
55 |
+
}
|
56 |
+
}
|
src/lib/src/Modules/HackGuard/AjaxHandler.php
CHANGED
@@ -11,13 +11,13 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
11 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
12 |
|
13 |
/**
|
14 |
-
* @param string $
|
15 |
* @return array
|
16 |
*/
|
17 |
-
protected function processAjaxAction( $
|
18 |
|
19 |
$oReq = Services::Request();
|
20 |
-
switch ( $
|
21 |
|
22 |
case 'scans_start':
|
23 |
$aResponse = $this->ajaxExec_StartScans();
|
@@ -40,7 +40,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
40 |
case 'item_delete':
|
41 |
case 'item_ignore':
|
42 |
case 'item_repair':
|
43 |
-
$aResponse = $this->ajaxExec_ScanItemAction( str_replace( 'item_', '', $
|
44 |
break;
|
45 |
|
46 |
case 'render_table_scan':
|
@@ -60,7 +60,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
60 |
break;
|
61 |
|
62 |
default:
|
63 |
-
$aResponse = parent::processAjaxAction( $
|
64 |
}
|
65 |
|
66 |
return $aResponse;
|
11 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
12 |
|
13 |
/**
|
14 |
+
* @param string $action
|
15 |
* @return array
|
16 |
*/
|
17 |
+
protected function processAjaxAction( $action ) {
|
18 |
|
19 |
$oReq = Services::Request();
|
20 |
+
switch ( $action ) {
|
21 |
|
22 |
case 'scans_start':
|
23 |
$aResponse = $this->ajaxExec_StartScans();
|
40 |
case 'item_delete':
|
41 |
case 'item_ignore':
|
42 |
case 'item_repair':
|
43 |
+
$aResponse = $this->ajaxExec_ScanItemAction( str_replace( 'item_', '', $action ) );
|
44 |
break;
|
45 |
|
46 |
case 'render_table_scan':
|
60 |
break;
|
61 |
|
62 |
default:
|
63 |
+
$aResponse = parent::processAjaxAction( $action );
|
64 |
}
|
65 |
|
66 |
return $aResponse;
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/File.php
CHANGED
@@ -26,36 +26,36 @@ class File {
|
|
26 |
* @return string[]
|
27 |
*/
|
28 |
public function getExistingPossiblePaths() {
|
29 |
-
|
30 |
$this->getPossiblePaths(),
|
31 |
function ( $sPath ) {
|
32 |
return Services::WpFs()->isFile( $sPath );
|
33 |
}
|
34 |
);
|
35 |
-
|
36 |
-
if ( (int)$this->max_paths > 0 ) {
|
37 |
-
$aPaths = array_slice( $aPaths, 0, $this->max_paths );
|
38 |
-
}
|
39 |
-
return $aPaths;
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
* @return string[]
|
44 |
*/
|
45 |
public function getPossiblePaths() {
|
46 |
-
$
|
47 |
-
$
|
48 |
-
$
|
49 |
do {
|
50 |
-
if ( empty( $
|
51 |
break;
|
52 |
}
|
53 |
-
$
|
54 |
-
|
55 |
-
$
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
-
return $
|
59 |
}
|
60 |
|
61 |
/**
|
26 |
* @return string[]
|
27 |
*/
|
28 |
public function getExistingPossiblePaths() {
|
29 |
+
return array_filter(
|
30 |
$this->getPossiblePaths(),
|
31 |
function ( $sPath ) {
|
32 |
return Services::WpFs()->isFile( $sPath );
|
33 |
}
|
34 |
);
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
* @return string[]
|
39 |
*/
|
40 |
public function getPossiblePaths() {
|
41 |
+
$paths = [];
|
42 |
+
$dirCount = 0;
|
43 |
+
$workingDir = realpath( $this->dir );
|
44 |
do {
|
45 |
+
if ( empty( $workingDir ) ) {
|
46 |
break;
|
47 |
}
|
48 |
+
$paths[] = path_join( $workingDir, $this->file );
|
49 |
+
|
50 |
+
$workingDir = dirname( $workingDir );
|
51 |
+
$dirCount++;
|
52 |
+
|
53 |
+
} while (
|
54 |
+
$dirCount < $this->getMaxDirLevels()
|
55 |
+
&& ( empty( $this->max_paths ) || count( $paths ) < $this->max_paths )
|
56 |
+
);
|
57 |
|
58 |
+
return $paths;
|
59 |
}
|
60 |
|
61 |
/**
|
src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php
CHANGED
@@ -123,15 +123,15 @@ class FileLockerController {
|
|
123 |
}
|
124 |
|
125 |
public function deleteAllLocks() {
|
126 |
-
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $
|
127 |
-
$
|
128 |
-
$
|
129 |
}
|
130 |
|
131 |
public function purge() {
|
132 |
-
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $
|
133 |
-
$
|
134 |
-
$
|
135 |
}
|
136 |
|
137 |
/**
|
@@ -181,14 +181,26 @@ class FileLockerController {
|
|
181 |
switch ( $sFileKey ) {
|
182 |
case 'wpconfig':
|
183 |
$sFileKey = 'wp-config.php';
|
184 |
-
$nLevels = $bIsSplitWp ? 3 : 2;
|
185 |
$nMaxPaths = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
// TODO: is split URL?
|
187 |
break;
|
|
|
188 |
case 'root_htaccess':
|
189 |
$sFileKey = '.htaccess';
|
190 |
$nLevels = $bIsSplitWp ? 2 : 1;
|
191 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
case 'root_index':
|
193 |
$sFileKey = 'index.php';
|
194 |
$nLevels = $bIsSplitWp ? 2 : 1;
|
123 |
}
|
124 |
|
125 |
public function deleteAllLocks() {
|
126 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
127 |
+
$mod = $this->getMod();
|
128 |
+
$mod->getDbHandler_FileLocker()->tableDelete( true );
|
129 |
}
|
130 |
|
131 |
public function purge() {
|
132 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
133 |
+
$mod = $this->getMod();
|
134 |
+
$mod->getDbHandler_FileLocker()->tableDelete();
|
135 |
}
|
136 |
|
137 |
/**
|
181 |
switch ( $sFileKey ) {
|
182 |
case 'wpconfig':
|
183 |
$sFileKey = 'wp-config.php';
|
|
|
184 |
$nMaxPaths = 1;
|
185 |
+
$nLevels = $bIsSplitWp ? 3 : 2;
|
186 |
+
|
187 |
+
$openBaseDir = ini_get( 'open_basedir' );
|
188 |
+
if ( !empty( $openBaseDir ) ) {
|
189 |
+
$nLevels--;
|
190 |
+
}
|
191 |
// TODO: is split URL?
|
192 |
break;
|
193 |
+
|
194 |
case 'root_htaccess':
|
195 |
$sFileKey = '.htaccess';
|
196 |
$nLevels = $bIsSplitWp ? 2 : 1;
|
197 |
break;
|
198 |
+
|
199 |
+
case 'root_webconfig':
|
200 |
+
$sFileKey = 'Web.Config';
|
201 |
+
$nLevels = $bIsSplitWp ? 2 : 1;
|
202 |
+
break;
|
203 |
+
|
204 |
case 'root_index':
|
205 |
$sFileKey = 'index.php';
|
206 |
$nLevels = $bIsSplitWp ? 2 : 1;
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/CleanAll.php
CHANGED
@@ -7,8 +7,6 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
7 |
|
8 |
class CleanAll extends BaseBulk {
|
9 |
|
10 |
-
/**
|
11 |
-
*/
|
12 |
public function run() {
|
13 |
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
|
14 |
$oMod = $this->getMod();
|
7 |
|
8 |
class CleanAll extends BaseBulk {
|
9 |
|
|
|
|
|
10 |
public function run() {
|
11 |
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
|
12 |
$oMod = $this->getMod();
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Delete.php
CHANGED
@@ -6,8 +6,6 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
6 |
|
7 |
class Delete extends BaseAction {
|
8 |
|
9 |
-
/**
|
10 |
-
*/
|
11 |
public function run() {
|
12 |
try {
|
13 |
$oStore = ( new Load() )
|
6 |
|
7 |
class Delete extends BaseAction {
|
8 |
|
|
|
|
|
9 |
public function run() {
|
10 |
try {
|
11 |
$oStore = ( new Load() )
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php
CHANGED
@@ -7,8 +7,6 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
7 |
|
8 |
class TouchAll extends BaseBulk {
|
9 |
|
10 |
-
/**
|
11 |
-
*/
|
12 |
public function run() {
|
13 |
foreach ( ( new FindAssetsToSnap() )->setMod( $this->getMod() )->run() as $oAsset ) {
|
14 |
try {
|
7 |
|
8 |
class TouchAll extends BaseBulk {
|
9 |
|
|
|
|
|
10 |
public function run() {
|
11 |
foreach ( ( new FindAssetsToSnap() )->setMod( $this->getMod() )->run() as $oAsset ) {
|
12 |
try {
|
src/lib/src/Modules/HackGuard/Options.php
CHANGED
@@ -9,6 +9,7 @@ class Options extends Base\ShieldOptions {
|
|
9 |
|
10 |
/**
|
11 |
* @return string[]
|
|
|
12 |
*/
|
13 |
public function getDbColumns_FileLocker() {
|
14 |
return $this->getDef( 'table_columns_filelocker' );
|
@@ -16,6 +17,7 @@ class Options extends Base\ShieldOptions {
|
|
16 |
|
17 |
/**
|
18 |
* @return string[]
|
|
|
19 |
*/
|
20 |
public function getDbColumns_Scanner() {
|
21 |
return $this->getDef( 'table_columns_scanner' );
|
@@ -23,6 +25,7 @@ class Options extends Base\ShieldOptions {
|
|
23 |
|
24 |
/**
|
25 |
* @return string[]
|
|
|
26 |
*/
|
27 |
public function getDbColumns_ScanQueue() {
|
28 |
return $this->getDef( 'table_columns_scanqueue' );
|
@@ -53,8 +56,8 @@ class Options extends Base\ShieldOptions {
|
|
53 |
* @return array
|
54 |
*/
|
55 |
public function getFilesToLock() {
|
56 |
-
$
|
57 |
-
return is_array( $
|
58 |
}
|
59 |
|
60 |
/**
|
9 |
|
10 |
/**
|
11 |
* @return string[]
|
12 |
+
* @deprecated 9.2.0
|
13 |
*/
|
14 |
public function getDbColumns_FileLocker() {
|
15 |
return $this->getDef( 'table_columns_filelocker' );
|
17 |
|
18 |
/**
|
19 |
* @return string[]
|
20 |
+
* @deprecated 9.2.0
|
21 |
*/
|
22 |
public function getDbColumns_Scanner() {
|
23 |
return $this->getDef( 'table_columns_scanner' );
|
25 |
|
26 |
/**
|
27 |
* @return string[]
|
28 |
+
* @deprecated 9.2.0
|
29 |
*/
|
30 |
public function getDbColumns_ScanQueue() {
|
31 |
return $this->getDef( 'table_columns_scanqueue' );
|
56 |
* @return array
|
57 |
*/
|
58 |
public function getFilesToLock() {
|
59 |
+
$locks = $this->getOpt( 'file_locker', [] );
|
60 |
+
return is_array( $locks ) ? $locks : [];
|
61 |
}
|
62 |
|
63 |
/**
|
src/lib/src/Modules/HackGuard/Scan/Queue/CompleteQueue.php
CHANGED
@@ -21,22 +21,23 @@ class CompleteQueue {
|
|
21 |
* Take care here not to confuse the 2x DB Handlers
|
22 |
*/
|
23 |
public function complete() {
|
24 |
-
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $
|
25 |
-
$
|
|
|
26 |
/** @var Databases\ScanQueue\Handler $oDbH */
|
27 |
$oDbH = $this->getDbHandler();
|
28 |
$oSel = $oDbH->getQuerySelector();
|
29 |
|
30 |
foreach ( $oSel->getDistinctForColumn( 'scan' ) as $sScanSlug ) {
|
31 |
|
32 |
-
$oScanCon = $
|
33 |
|
34 |
$oResultsSet = ( new CollateResults() )
|
35 |
->setScanController( $oScanCon )
|
36 |
->setDbHandler( $oDbH )
|
37 |
->collate( $sScanSlug );
|
38 |
|
39 |
-
$
|
40 |
|
41 |
if ( $oResultsSet instanceof Scans\Base\BaseResultsSet ) {
|
42 |
( new HackGuard\Scan\Results\ResultsUpdate() )
|
@@ -44,7 +45,7 @@ class CompleteQueue {
|
|
44 |
->update( $oResultsSet );
|
45 |
|
46 |
if ( $oResultsSet->countItems() > 0 ) {
|
47 |
-
$
|
48 |
}
|
49 |
}
|
50 |
|
@@ -54,14 +55,14 @@ class CompleteQueue {
|
|
54 |
->query();
|
55 |
}
|
56 |
|
57 |
-
/** @var HackGuard\Options $
|
58 |
-
$
|
59 |
-
if ( $
|
60 |
wp_schedule_single_event(
|
61 |
Services::Request()->ts() + 5,
|
62 |
-
$
|
63 |
);
|
64 |
}
|
65 |
-
$
|
66 |
}
|
67 |
}
|
21 |
* Take care here not to confuse the 2x DB Handlers
|
22 |
*/
|
23 |
public function complete() {
|
24 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
25 |
+
$mod = $this->getMod();
|
26 |
+
$con = $this->getCon();
|
27 |
/** @var Databases\ScanQueue\Handler $oDbH */
|
28 |
$oDbH = $this->getDbHandler();
|
29 |
$oSel = $oDbH->getQuerySelector();
|
30 |
|
31 |
foreach ( $oSel->getDistinctForColumn( 'scan' ) as $sScanSlug ) {
|
32 |
|
33 |
+
$oScanCon = $mod->getScanCon( $sScanSlug );
|
34 |
|
35 |
$oResultsSet = ( new CollateResults() )
|
36 |
->setScanController( $oScanCon )
|
37 |
->setDbHandler( $oDbH )
|
38 |
->collate( $sScanSlug );
|
39 |
|
40 |
+
$con->fireEvent( $sScanSlug.'_scan_run' );
|
41 |
|
42 |
if ( $oResultsSet instanceof Scans\Base\BaseResultsSet ) {
|
43 |
( new HackGuard\Scan\Results\ResultsUpdate() )
|
45 |
->update( $oResultsSet );
|
46 |
|
47 |
if ( $oResultsSet->countItems() > 0 ) {
|
48 |
+
$con->fireEvent( $sScanSlug.'_scan_found' );
|
49 |
}
|
50 |
}
|
51 |
|
55 |
->query();
|
56 |
}
|
57 |
|
58 |
+
/** @var HackGuard\Options $opts */
|
59 |
+
$opts = $this->getOptions();
|
60 |
+
if ( $opts->isScanCron() && !wp_next_scheduled( $con->prefix( 'post_scan' ) ) ) {
|
61 |
wp_schedule_single_event(
|
62 |
Services::Request()->ts() + 5,
|
63 |
+
$con->prefix( 'post_scan' )
|
64 |
);
|
65 |
}
|
66 |
+
$opts->setIsScanCron( false );
|
67 |
}
|
68 |
}
|
src/lib/src/Modules/HackGuard/Scan/Queue/ConvertBetweenTypes.php
CHANGED
@@ -32,7 +32,7 @@ class ConvertBetweenTypes {
|
|
32 |
*/
|
33 |
public function fromActionToDbEntry( $oAction ) {
|
34 |
$oEntry = new Databases\ScanQueue\EntryVO();
|
35 |
-
foreach ( $this->getDbHandler()->
|
36 |
if ( isset( $oAction->{$sField} ) ) {
|
37 |
$oEntry->{$sField} = $oAction->{$sField};
|
38 |
}
|
32 |
*/
|
33 |
public function fromActionToDbEntry( $oAction ) {
|
34 |
$oEntry = new Databases\ScanQueue\EntryVO();
|
35 |
+
foreach ( $this->getDbHandler()->getColumns() as $sField ) {
|
36 |
if ( isset( $oAction->{$sField} ) ) {
|
37 |
$oEntry->{$sField} = $oAction->{$sField};
|
38 |
}
|
src/lib/src/Modules/HackGuard/Scan/Queue/QueueProcessor.php
CHANGED
@@ -140,8 +140,6 @@ class QueueProcessor extends Utilities\BackgroundProcessing\BackgroundProcess {
|
|
140 |
return $this;
|
141 |
}
|
142 |
|
143 |
-
/**
|
144 |
-
*/
|
145 |
public function handleExpiredItems() {
|
146 |
$nBoundary = Services::Request()
|
147 |
->carbon()
|
140 |
return $this;
|
141 |
}
|
142 |
|
|
|
|
|
143 |
public function handleExpiredItems() {
|
144 |
$nBoundary = Services::Request()
|
145 |
->carbon()
|
src/lib/src/Modules/HackGuard/Strings.php
CHANGED
@@ -61,15 +61,15 @@ class Strings extends Base\Strings {
|
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
-
* @param string $
|
65 |
* @return array
|
66 |
* @throws \Exception
|
67 |
*/
|
68 |
-
public function getSectionStrings( $
|
69 |
|
70 |
$sModName = $this->getMod()->getMainFeatureName();
|
71 |
|
72 |
-
switch ( $
|
73 |
|
74 |
case 'section_scan_options' :
|
75 |
$sTitle = __( 'Scan Options', 'wp-simple-firewall' );
|
@@ -159,7 +159,7 @@ class Strings extends Base\Strings {
|
|
159 |
break;
|
160 |
|
161 |
default:
|
162 |
-
return parent::getSectionStrings( $
|
163 |
}
|
164 |
|
165 |
return [
|
@@ -170,16 +170,16 @@ class Strings extends Base\Strings {
|
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
-
* @param string $
|
174 |
* @return array
|
175 |
* @throws \Exception
|
176 |
*/
|
177 |
-
public function getOptionStrings( $
|
178 |
-
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $
|
179 |
-
$
|
180 |
-
$sModName = $
|
181 |
|
182 |
-
switch ( $
|
183 |
|
184 |
case 'enable_hack_protect' :
|
185 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -247,9 +247,9 @@ class Strings extends Base\Strings {
|
|
247 |
sprintf( '%s - %s', __( 'Important', 'wp-simple-firewall' ), __( "Doesn't currently detect missing files.", 'wp-simple-firewall' ) ),
|
248 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Keep this feature turned on, at all times.', 'wp-simple-firewall' ) )
|
249 |
];
|
250 |
-
if ( !$
|
251 |
$sDescription[] = sprintf( __( 'Sorry, this feature is not available because we cannot write to disk at this location: %s', 'wp-simple-firewall' ),
|
252 |
-
'<code>'.$
|
253 |
}
|
254 |
break;
|
255 |
|
@@ -270,6 +270,7 @@ class Strings extends Base\Strings {
|
|
270 |
$sSummary = __( 'Lock Files Against Tampering And Changes', 'wp-simple-firewall' );
|
271 |
$sDescription = [
|
272 |
__( 'Detects changes to the files, then lets you examine contents and revert as required.', 'wp-simple-firewall' ),
|
|
|
273 |
];
|
274 |
|
275 |
$aLocks = ( new LoadFileLocks() )
|
@@ -299,7 +300,7 @@ class Strings extends Base\Strings {
|
|
299 |
case 'ufc_exclusions' :
|
300 |
$sName = __( 'File Exclusions', 'wp-simple-firewall' );
|
301 |
$sSummary = __( 'Provide A List Of Files To Be Excluded From The Scan', 'wp-simple-firewall' );
|
302 |
-
$sDefaults = implode( ', ', $
|
303 |
$sDescription = __( 'Take a new line for each file you wish to exclude from the scan.', 'wp-simple-firewall' )
|
304 |
.'<br/><strong>'.__( 'No commas are necessary.', 'wp-simple-firewall' ).'</strong>'
|
305 |
.'<br/>'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $sDefaults );
|
@@ -415,7 +416,7 @@ class Strings extends Base\Strings {
|
|
415 |
.'<br/>'.__( 'Remove all extensions to scan all file type (not recommended).', 'wp-simple-firewall' );
|
416 |
break;
|
417 |
default:
|
418 |
-
return parent::getOptionStrings( $
|
419 |
}
|
420 |
|
421 |
return [
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
+
* @param string $section
|
65 |
* @return array
|
66 |
* @throws \Exception
|
67 |
*/
|
68 |
+
public function getSectionStrings( $section ) {
|
69 |
|
70 |
$sModName = $this->getMod()->getMainFeatureName();
|
71 |
|
72 |
+
switch ( $section ) {
|
73 |
|
74 |
case 'section_scan_options' :
|
75 |
$sTitle = __( 'Scan Options', 'wp-simple-firewall' );
|
159 |
break;
|
160 |
|
161 |
default:
|
162 |
+
return parent::getSectionStrings( $section );
|
163 |
}
|
164 |
|
165 |
return [
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
+
* @param string $key
|
174 |
* @return array
|
175 |
* @throws \Exception
|
176 |
*/
|
177 |
+
public function getOptionStrings( $key ) {
|
178 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
179 |
+
$mod = $this->getMod();
|
180 |
+
$sModName = $mod->getMainFeatureName();
|
181 |
|
182 |
+
switch ( $key ) {
|
183 |
|
184 |
case 'enable_hack_protect' :
|
185 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
247 |
sprintf( '%s - %s', __( 'Important', 'wp-simple-firewall' ), __( "Doesn't currently detect missing files.", 'wp-simple-firewall' ) ),
|
248 |
sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Keep this feature turned on, at all times.', 'wp-simple-firewall' ) )
|
249 |
];
|
250 |
+
if ( !$mod->canCacheDirWrite() ) {
|
251 |
$sDescription[] = sprintf( __( 'Sorry, this feature is not available because we cannot write to disk at this location: %s', 'wp-simple-firewall' ),
|
252 |
+
'<code>'.$mod->getPtgSnapsBaseDir().'</code>' );
|
253 |
}
|
254 |
break;
|
255 |
|
270 |
$sSummary = __( 'Lock Files Against Tampering And Changes', 'wp-simple-firewall' );
|
271 |
$sDescription = [
|
272 |
__( 'Detects changes to the files, then lets you examine contents and revert as required.', 'wp-simple-firewall' ),
|
273 |
+
sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ), __( 'Web.Config is only available for Windows/IIS.', 'wp-simple-firewall' ) )
|
274 |
];
|
275 |
|
276 |
$aLocks = ( new LoadFileLocks() )
|
300 |
case 'ufc_exclusions' :
|
301 |
$sName = __( 'File Exclusions', 'wp-simple-firewall' );
|
302 |
$sSummary = __( 'Provide A List Of Files To Be Excluded From The Scan', 'wp-simple-firewall' );
|
303 |
+
$sDefaults = implode( ', ', $this->getOptions()->getOptDefault( 'ufc_exclusions' ) );
|
304 |
$sDescription = __( 'Take a new line for each file you wish to exclude from the scan.', 'wp-simple-firewall' )
|
305 |
.'<br/><strong>'.__( 'No commas are necessary.', 'wp-simple-firewall' ).'</strong>'
|
306 |
.'<br/>'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $sDefaults );
|
416 |
.'<br/>'.__( 'Remove all extensions to scan all file type (not recommended).', 'wp-simple-firewall' );
|
417 |
break;
|
418 |
default:
|
419 |
+
return parent::getOptionStrings( $key );
|
420 |
}
|
421 |
|
422 |
return [
|
src/lib/src/Modules/HackGuard/UI.php
ADDED
@@ -0,0 +1,703 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\FileLocker\Ops\LoadFileLocks;
|
8 |
+
use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
|
9 |
+
use FernleafSystems\Wordpress\Services\Services;
|
10 |
+
|
11 |
+
class UI extends Base\ShieldUI {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
public function buildInsightsVars() {
|
17 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
18 |
+
$mod = $this->getMod();
|
19 |
+
/** @var Options $opts */
|
20 |
+
$opts = $this->getOptions();
|
21 |
+
|
22 |
+
$aLatestScans = array_map(
|
23 |
+
function ( $nTime ) {
|
24 |
+
return sprintf(
|
25 |
+
__( 'Last Scan: %s', 'wp-simple-firewall' ),
|
26 |
+
( $nTime > 0 ) ?
|
27 |
+
Services::Request()->carbon()->setTimestamp( $nTime )->diffForHumans()
|
28 |
+
: __( 'Never', 'wp-simple-firewall' )
|
29 |
+
);
|
30 |
+
},
|
31 |
+
$mod->getLastScansAt()
|
32 |
+
);
|
33 |
+
|
34 |
+
$aUiTrack = $mod->getUiTrack();
|
35 |
+
if ( empty( $aUiTrack[ 'selected_scans' ] ) ) {
|
36 |
+
$aUiTrack[ 'selected_scans' ] = $opts->getScanSlugs();
|
37 |
+
}
|
38 |
+
|
39 |
+
// Can Scan Checks:
|
40 |
+
$aReasonCantScan = $mod->getProcessor()
|
41 |
+
->getSubProScanner()
|
42 |
+
->getReasonsScansCantExecute();
|
43 |
+
|
44 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\Select $oSelector */
|
45 |
+
$oSelector = $mod->getDbHandler_ScanResults()->getQuerySelector();
|
46 |
+
$aData = [
|
47 |
+
'ajax' => [
|
48 |
+
'scans_start' => $mod->getAjaxActionData( 'scans_start', true ),
|
49 |
+
'scans_check' => $mod->getAjaxActionData( 'scans_check', true ),
|
50 |
+
'render_table_scan' => $mod->getAjaxActionData( 'render_table_scan', true ),
|
51 |
+
'bulk_action' => $mod->getAjaxActionData( 'bulk_action', true ),
|
52 |
+
'item_asset_deactivate' => $mod->getAjaxActionData( 'item_asset_deactivate', true ),
|
53 |
+
'item_asset_reinstall' => $mod->getAjaxActionData( 'item_asset_reinstall', true ),
|
54 |
+
'item_delete' => $mod->getAjaxActionData( 'item_delete', true ),
|
55 |
+
'item_ignore' => $mod->getAjaxActionData( 'item_ignore', true ),
|
56 |
+
'item_repair' => $mod->getAjaxActionData( 'item_repair', true ),
|
57 |
+
'item_action' => $mod->getAjaxActionData( 'item_action', true ),
|
58 |
+
],
|
59 |
+
'flags' => [
|
60 |
+
'is_premium' => $this->getCon()->isPremiumActive(),
|
61 |
+
'can_scan' => count( $aReasonCantScan ) === 0,
|
62 |
+
],
|
63 |
+
'strings' => [
|
64 |
+
'never' => __( 'Never', 'wp-simple-firewall' ),
|
65 |
+
'not_available' => __( 'Sorry, this scan is not available.', 'wp-simple-firewall' ),
|
66 |
+
'not_enabled' => __( 'This scan is not currently enabled.', 'wp-simple-firewall' ),
|
67 |
+
'please_enable' => __( 'Please turn on this scan in the options.', 'wp-simple-firewall' ),
|
68 |
+
'click_see_results' => __( 'Click a scan to see its results', 'wp-simple-firewall' ),
|
69 |
+
'title_scan_site_now' => __( 'Scan Your Site Now', 'wp-simple-firewall' ),
|
70 |
+
'title_scan_now' => __( 'Scan Your Site Now', 'wp-simple-firewall' ),
|
71 |
+
'subtitle_scan_now' => __( 'Run the selected scans on your site now to get the latest results', 'wp-simple-firewall' ),
|
72 |
+
'more_items_longer' => __( 'The more scans that are selected, the longer the scan may take.', 'wp-simple-firewall' ),
|
73 |
+
'scan_options' => __( 'Scan Options', 'wp-simple-firewall' ),
|
74 |
+
'scanselect' => __( 'Select Scans To Run', 'wp-simple-firewall' ),
|
75 |
+
'scanselect_file_areas' => __( 'Select File Scans To Run', 'wp-simple-firewall' ),
|
76 |
+
'scanselect_assets' => __( 'Select Scans For Plugins and Themes', 'wp-simple-firewall' ),
|
77 |
+
'select_view_results' => __( 'View Scan Results', 'wp-simple-firewall' ),
|
78 |
+
'select_what_to_scan' => __( 'Select Scans To Run', 'wp-simple-firewall' ),
|
79 |
+
'clear_ignore' => __( 'Clear Ignore Flags', 'wp-simple-firewall' ),
|
80 |
+
'clear_ignore_sub' => __( 'Previously ignored results will be revealed (for the selected scans only)', 'wp-simple-firewall' ),
|
81 |
+
'clear_suppression' => __( 'Remove Notification Suppression', 'wp-simple-firewall' ),
|
82 |
+
'clear_suppression_sub' => __( 'Allow notification emails to be resent (for the selected scans only)', 'wp-simple-firewall' ),
|
83 |
+
'run_scans_now' => __( 'Run Scans Now', 'wp-simple-firewall' ),
|
84 |
+
'no_entries_to_display' => __( "The previous scan either didn't detect any items that require your attention or they've already been repaired.", 'wp-simple-firewall' ),
|
85 |
+
'scan_progress' => __( 'Scan Progress', 'wp-simple-firewall' ),
|
86 |
+
'reason_not_call_self' => __( "This site currently can't make HTTP requests to itself.", 'wp-simple-firewall' ),
|
87 |
+
],
|
88 |
+
'vars' => [
|
89 |
+
'initial_check' => $mod->getScanQueueController()->hasRunningScans(),
|
90 |
+
'cannot_scan_reasons' => $aReasonCantScan
|
91 |
+
],
|
92 |
+
'scan_results' => [
|
93 |
+
],
|
94 |
+
'aggregate' => [
|
95 |
+
'flags' => [
|
96 |
+
'has_items' => true,
|
97 |
+
],
|
98 |
+
'hrefs' => [
|
99 |
+
'options' => $mod->getUrl_DirectLinkToSection( 'section_scan_options' )
|
100 |
+
],
|
101 |
+
'vars' => [
|
102 |
+
],
|
103 |
+
'strings' => [
|
104 |
+
'title' => __( 'File Scan', 'wp-simple-firewall' ),
|
105 |
+
'subtitle' => __( "Results of all file scans", 'wp-simple-firewall' )
|
106 |
+
],
|
107 |
+
'count' => $oSelector->filterByScans( [ 'ptg', 'mal', 'wcf', 'ufc' ] )
|
108 |
+
->filterByNotIgnored()
|
109 |
+
->count()
|
110 |
+
],
|
111 |
+
'file_locker' => $this->getFileLockerVars(),
|
112 |
+
'scans' => [
|
113 |
+
'apc' => [
|
114 |
+
'flags' => [
|
115 |
+
'has_items' => true,
|
116 |
+
'show_table' => true,
|
117 |
+
],
|
118 |
+
'hrefs' => [],
|
119 |
+
'vars' => [],
|
120 |
+
'strings' => [
|
121 |
+
'subtitle' => __( "Discover plugins that may have been abandoned by their authors", 'wp-simple-firewall' )
|
122 |
+
],
|
123 |
+
],
|
124 |
+
'wcf' => [
|
125 |
+
'flags' => [
|
126 |
+
'has_items' => true,
|
127 |
+
'show_table' => false,
|
128 |
+
],
|
129 |
+
'hrefs' => [],
|
130 |
+
'vars' => [],
|
131 |
+
'strings' => [
|
132 |
+
'subtitle' => __( "Detect changes to core WordPress files when compared to the official distribution", 'wp-simple-firewall' ),
|
133 |
+
],
|
134 |
+
],
|
135 |
+
'ufc' => [
|
136 |
+
'flags' => [
|
137 |
+
'has_items' => true,
|
138 |
+
'show_table' => false,
|
139 |
+
],
|
140 |
+
'hrefs' => [],
|
141 |
+
'vars' => [],
|
142 |
+
'strings' => [
|
143 |
+
'subtitle' => __( "Detect files which aren't part of the official WordPress.org distribution", 'wp-simple-firewall' )
|
144 |
+
],
|
145 |
+
],
|
146 |
+
'mal' => [
|
147 |
+
'flags' => [
|
148 |
+
'has_items' => true,
|
149 |
+
'show_table' => false,
|
150 |
+
],
|
151 |
+
'hrefs' => [],
|
152 |
+
'vars' => [],
|
153 |
+
'strings' => [
|
154 |
+
'subtitle' => __( "Detect files that may be infected with malware", 'wp-simple-firewall' )
|
155 |
+
],
|
156 |
+
],
|
157 |
+
'ptg' => $this->getInsightVarsScan_Ptg(),
|
158 |
+
'wpv' => [
|
159 |
+
'flags' => [
|
160 |
+
'has_items' => true,
|
161 |
+
'show_table' => true,
|
162 |
+
],
|
163 |
+
'hrefs' => [],
|
164 |
+
'vars' => [],
|
165 |
+
'strings' => [
|
166 |
+
'subtitle' => __( "Be alerted to plugins and themes with known security vulnerabilities", 'wp-simple-firewall' )
|
167 |
+
],
|
168 |
+
],
|
169 |
+
],
|
170 |
+
];
|
171 |
+
|
172 |
+
/** @var Strings $oStrings */
|
173 |
+
$oStrings = $mod->getStrings();
|
174 |
+
$aScanNames = $oStrings->getScanNames();
|
175 |
+
foreach ( $aData[ 'scans' ] as $sSlug => &$aScanData ) {
|
176 |
+
$oScanCon = $mod->getScanCon( $sSlug );
|
177 |
+
$aScanData[ 'flags' ][ 'is_available' ] = $oScanCon->isScanningAvailable();
|
178 |
+
$aScanData[ 'flags' ][ 'is_restricted' ] = !$oScanCon->isScanningAvailable();
|
179 |
+
$aScanData[ 'flags' ][ 'is_enabled' ] = $oScanCon->isEnabled();
|
180 |
+
$aScanData[ 'flags' ][ 'is_selected' ] = $oScanCon->isScanningAvailable() && in_array( $sSlug, $aUiTrack[ 'selected_scans' ] );
|
181 |
+
$aScanData[ 'flags' ][ 'has_last_scan' ] = $mod->getLastScanAt( $sSlug ) > 0;
|
182 |
+
$aScanData[ 'vars' ][ 'last_scan_at' ] = $aLatestScans[ $sSlug ];
|
183 |
+
$aScanData[ 'strings' ][ 'title' ] = $aScanNames[ $sSlug ];
|
184 |
+
$aScanData[ 'hrefs' ][ 'options' ] = $mod->getUrl_DirectLinkToSection( 'section_scan_'.$sSlug );
|
185 |
+
$aScanData[ 'hrefs' ][ 'please_enable' ] = $mod->getUrl_DirectLinkToSection( 'section_scan_'.$sSlug );
|
186 |
+
$aScanData[ 'count' ] = $oSelector->countForScan( $sSlug );
|
187 |
+
}
|
188 |
+
|
189 |
+
return $aData;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* @param array $aOptParams
|
194 |
+
* @return array
|
195 |
+
*/
|
196 |
+
protected function buildOptionForUi( $aOptParams ) {
|
197 |
+
$aOptParams = parent::buildOptionForUi( $aOptParams );
|
198 |
+
if ( $aOptParams[ 'key' ] === 'file_locker' && !Services::Data()->isWindows() ) {
|
199 |
+
$aOptParams[ 'value_options' ][ 'root_webconfig' ] .= sprintf( ' (%s)', __( 'unavailable', 'wp-simple-firewall' ) );
|
200 |
+
}
|
201 |
+
return $aOptParams;
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* @return array
|
206 |
+
*/
|
207 |
+
protected function getFileLockerVars() {
|
208 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
209 |
+
$mod = $this->getMod();
|
210 |
+
|
211 |
+
$oLockCon = $mod->getFileLocker();
|
212 |
+
$oLockLoader = ( new LoadFileLocks() )->setMod( $mod );
|
213 |
+
$aProblemLocks = $oLockLoader->withProblems();
|
214 |
+
$aGoodLocks = $oLockLoader->withoutProblems();
|
215 |
+
|
216 |
+
return [
|
217 |
+
'ajax' => [
|
218 |
+
'filelocker_showdiff' => $mod->getAjaxActionData( 'filelocker_showdiff', true ),
|
219 |
+
'filelocker_fileaction' => $mod->getAjaxActionData( 'filelocker_fileaction', true ),
|
220 |
+
],
|
221 |
+
'flags' => [
|
222 |
+
'is_enabled' => $oLockCon->isEnabled(),
|
223 |
+
'is_restricted' => !$this->getCon()->isPremiumActive(),
|
224 |
+
],
|
225 |
+
'hrefs' => [
|
226 |
+
'options' => $mod->getUrl_DirectLinkToSection( 'section_realtime' ),
|
227 |
+
'please_enable' => $mod->getUrl_DirectLinkToSection( 'section_realtime' ),
|
228 |
+
],
|
229 |
+
'vars' => [
|
230 |
+
'file_locks' => [
|
231 |
+
'good' => $aGoodLocks,
|
232 |
+
'bad' => $aProblemLocks,
|
233 |
+
],
|
234 |
+
],
|
235 |
+
'strings' => [
|
236 |
+
'title' => __( 'File Locker', 'wp-simple-firewall' ),
|
237 |
+
'subtitle' => __( 'Results of file locker monitoring', 'wp-simple-firewall' ),
|
238 |
+
'please_select' => __( 'Please select a file to review.', 'wp-simple-firewall' ),
|
239 |
+
],
|
240 |
+
'count' => count( $aProblemLocks )
|
241 |
+
];
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* @return array
|
246 |
+
*/
|
247 |
+
private function getInsightVarsScan_Ptg() {
|
248 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
|
249 |
+
$oMod = $this->getMod();
|
250 |
+
$oReq = Services::Request();
|
251 |
+
|
252 |
+
/** @var \ICWP_WPSF_Processor_HackProtect $oPro */
|
253 |
+
$oPro = $oMod->getProcessor();
|
254 |
+
$oProPtg = $oPro->getSubProScanner()->getSubProcessorPtg();
|
255 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\Select $oSelector */
|
256 |
+
$oSelector = $oMod->getDbHandler_ScanResults()->getQuerySelector();
|
257 |
+
|
258 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO[] $aPtgResults */
|
259 |
+
$aPtgResults = $oSelector->filterByNotIgnored()
|
260 |
+
->filterByScan( 'ptg' )
|
261 |
+
->query();
|
262 |
+
/** @var Shield\Scans\Ptg\ResultsSet $oFullResults */
|
263 |
+
$oFullResults = ( new Shield\Modules\HackGuard\Scan\Results\ConvertBetweenTypes() )
|
264 |
+
->setScanController( $oMod->getScanCon( 'ptg' ) )
|
265 |
+
->fromVOsToResultsSet( $aPtgResults );
|
266 |
+
|
267 |
+
// Process Plugins
|
268 |
+
$aPlugins = $oFullResults->getAllResultsSetsForPluginsContext();
|
269 |
+
$oWpPlugins = Services::WpPlugins();
|
270 |
+
foreach ( $aPlugins as $sSlug => $oItemRS ) {
|
271 |
+
$aItems = $oItemRS->getAllItems();
|
272 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg\ResultItem $oIT */
|
273 |
+
$oIT = array_pop( $aItems );
|
274 |
+
$aMeta = $oProPtg->getSnapshotItemMeta( $oIT->slug );
|
275 |
+
if ( !empty( $aMeta[ 'ts' ] ) ) {
|
276 |
+
$aMeta[ 'ts' ] = $oReq->carbon()->setTimestamp( $aMeta[ 'ts' ] )->diffForHumans();
|
277 |
+
}
|
278 |
+
else {
|
279 |
+
$aMeta[ 'ts' ] = __( 'unknown', 'wp-simple-firewall' );
|
280 |
+
}
|
281 |
+
|
282 |
+
$bInstalled = $oWpPlugins->isInstalled( $oIT->slug );
|
283 |
+
$oPlgn = $oWpPlugins->getPluginAsVo( $oIT->slug );
|
284 |
+
$bIsWpOrg = $bInstalled && $oPlgn instanceof WpPluginVo && $oPlgn->isWpOrg();
|
285 |
+
$bHasUpdate = $bIsWpOrg && $oPlgn->hasUpdate();
|
286 |
+
$aProfile = [
|
287 |
+
'id' => $oSelector->filterByHash( $oIT->hash )->first()->id,
|
288 |
+
'name' => __( 'unknown', 'wp-simple-firewall' ),
|
289 |
+
'version' => __( 'unknown', 'wp-simple-firewall' ),
|
290 |
+
'root_dir' => $oWpPlugins->getInstallationDir( $oIT->slug ),
|
291 |
+
'slug' => $sSlug,
|
292 |
+
'is_wporg' => $bIsWpOrg,
|
293 |
+
'can_reinstall' => $bIsWpOrg,
|
294 |
+
'can_deactivate' => $bInstalled && ( $sSlug !== $this->getCon()->getPluginBaseFile() ),
|
295 |
+
'has_update' => $bHasUpdate,
|
296 |
+
'count_files' => $oItemRS->countItems(),
|
297 |
+
'date_snapshot' => $aMeta[ 'ts' ],
|
298 |
+
];
|
299 |
+
|
300 |
+
if ( $bInstalled ) {
|
301 |
+
$oP = $oWpPlugins->getPluginAsVo( $oIT->slug );
|
302 |
+
$aProfile[ 'name' ] = $oP->Name;
|
303 |
+
$aProfile[ 'version' ] = $oP->Version;
|
304 |
+
}
|
305 |
+
else {
|
306 |
+
// MISSING!
|
307 |
+
if ( is_array( $aMeta ) ) {
|
308 |
+
$aProfile[ 'name' ] = isset( $aMeta[ 'name' ] ) ? $aMeta[ 'name' ] : __( 'unknown', 'wp-simple-firewall' );
|
309 |
+
$aProfile[ 'version' ] = isset( $aMeta[ 'version' ] ) ? $aMeta[ 'version' ] : __( 'unknown', 'wp-simple-firewall' );
|
310 |
+
}
|
311 |
+
}
|
312 |
+
$aProfile[ 'name' ] = sprintf( '%s: %s', __( 'Plugin' ), $aProfile[ 'name' ] );
|
313 |
+
|
314 |
+
$aPlugins[ $sSlug ] = $aProfile;
|
315 |
+
}
|
316 |
+
|
317 |
+
// Process Themes
|
318 |
+
$aThemes = $oFullResults->getAllResultsSetsForThemesContext();
|
319 |
+
$oWpThemes = Services::WpThemes();
|
320 |
+
foreach ( $aThemes as $sSlug => $oItemRS ) {
|
321 |
+
$aItems = $oItemRS->getAllItems();
|
322 |
+
/** @var \FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg\ResultItem $oIT */
|
323 |
+
$oIT = array_pop( $aItems );
|
324 |
+
$aMeta = $oProPtg->getSnapshotItemMeta( $oIT->slug );
|
325 |
+
if ( !empty( $aMeta[ 'ts' ] ) ) {
|
326 |
+
$aMeta[ 'ts' ] = $oReq->carbon()->setTimestamp( $aMeta[ 'ts' ] )->diffForHumans();
|
327 |
+
}
|
328 |
+
else {
|
329 |
+
$aMeta[ 'ts' ] = __( 'unknown', 'wp-simple-firewall' );
|
330 |
+
}
|
331 |
+
|
332 |
+
$bInstalled = $oWpThemes->isInstalled( $oIT->slug );
|
333 |
+
$bIsWpOrg = $bInstalled && $oWpThemes->isWpOrg( $sSlug );
|
334 |
+
$bHasUpdate = $bIsWpOrg && $oWpThemes->isUpdateAvailable( $sSlug );
|
335 |
+
$aProfile = [
|
336 |
+
'id' => $oSelector->filterByHash( $oIT->hash )->first()->id,
|
337 |
+
'name' => __( 'unknown', 'wp-simple-firewall' ),
|
338 |
+
'version' => __( 'unknown', 'wp-simple-firewall' ),
|
339 |
+
'root_dir' => __( 'unknown', 'wp-simple-firewall' ),
|
340 |
+
'slug' => $sSlug,
|
341 |
+
'is_wporg' => $bIsWpOrg,
|
342 |
+
'can_reinstall' => $bIsWpOrg,
|
343 |
+
'can_deactivate' => false,
|
344 |
+
'has_update' => $bHasUpdate,
|
345 |
+
'count_files' => $oItemRS->countItems(),
|
346 |
+
'date_snapshot' => $aMeta[ 'ts' ],
|
347 |
+
];
|
348 |
+
if ( $bInstalled ) {
|
349 |
+
$oT = $oWpThemes->getTheme( $oIT->slug );
|
350 |
+
$aProfile[ 'name' ] = $oT->get( 'Name' );
|
351 |
+
$aProfile[ 'version' ] = $oT->get( 'Version' );
|
352 |
+
$aProfile[ 'root_dir' ] = $oWpThemes->getInstallationDir( $oIT->slug );
|
353 |
+
}
|
354 |
+
$aProfile[ 'name' ] = sprintf( '%s: %s', __( 'Theme' ), $aProfile[ 'name' ] );
|
355 |
+
|
356 |
+
$aThemes[ $sSlug ] = $aProfile;
|
357 |
+
}
|
358 |
+
|
359 |
+
return [
|
360 |
+
'flags' => [
|
361 |
+
'has_items' => $oMod->isPtgEnabled() ? $oFullResults->hasItems() : false,
|
362 |
+
'has_plugins' => !empty( $aPlugins ),
|
363 |
+
'has_themes' => !empty( $aThemes ),
|
364 |
+
'show_table' => false,
|
365 |
+
],
|
366 |
+
'hrefs' => [],
|
367 |
+
'vars' => [],
|
368 |
+
'assets' => $oMod->isPtgEnabled() ? array_merge( $aPlugins, $aThemes ) : [],
|
369 |
+
'strings' => [
|
370 |
+
'subtitle' => __( "Detects unauthorized changes to plugins/themes", 'wp-simple-firewall' ),
|
371 |
+
'files_with_problems' => __( 'Files with problems', 'wp-simple-firewall' ),
|
372 |
+
'root_dir' => __( 'Root directory', 'wp-simple-firewall' ),
|
373 |
+
'date_snapshot' => __( 'Snapshot taken', 'wp-simple-firewall' ),
|
374 |
+
'reinstall' => __( 'Re-Install', 'wp-simple-firewall' ),
|
375 |
+
'deactivate' => __( 'Deactivate and Ignore', 'wp-simple-firewall' ),
|
376 |
+
'accept' => __( 'Accept', 'wp-simple-firewall' ),
|
377 |
+
'update' => __( 'Upgrade', 'wp-simple-firewall' ),
|
378 |
+
]
|
379 |
+
];
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* @return array
|
384 |
+
*/
|
385 |
+
public function getInsightsConfigCardData() {
|
386 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
387 |
+
$mod = $this->getMod();
|
388 |
+
/** @var Options $opts */
|
389 |
+
$opts = $this->getOptions();
|
390 |
+
$aScanNames = $mod->getStrings()->getScanNames();
|
391 |
+
|
392 |
+
$data = [
|
393 |
+
'strings' => [
|
394 |
+
'title' => __( 'Hack Guard', 'wp-simple-firewall' ),
|
395 |
+
'sub' => __( 'Threats/Intrusions Detection & Repair', 'wp-simple-firewall' ),
|
396 |
+
],
|
397 |
+
'key_opts' => [],
|
398 |
+
'href_options' => $mod->getUrl_AdminPage()
|
399 |
+
];
|
400 |
+
|
401 |
+
if ( !$mod->isModOptEnabled() ) {
|
402 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
403 |
+
}
|
404 |
+
else {
|
405 |
+
$bGoodFrequency = $opts->getScanFrequency() > 1;
|
406 |
+
$data[ 'key_opts' ][ 'frequency' ] = [
|
407 |
+
'name' => __( 'Scan Frequency', 'wp-simple-firewall' ),
|
408 |
+
'enabled' => $bGoodFrequency,
|
409 |
+
'summary' => $bGoodFrequency ?
|
410 |
+
__( 'Automatic scanners run more than once per day', 'wp-simple-firewall' )
|
411 |
+
: __( "Automatic scanners only run once per day", 'wp-simple-firewall' ),
|
412 |
+
'weight' => 1,
|
413 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_options' ),
|
414 |
+
];
|
415 |
+
|
416 |
+
$bCore = $mod->getScanCon( 'wcf' )->isEnabled();
|
417 |
+
$data[ 'key_opts' ][ 'wcf' ] = [
|
418 |
+
'name' => __( 'WP Core File Scan', 'wp-simple-firewall' ),
|
419 |
+
'enabled' => $bCore,
|
420 |
+
'summary' => $bCore ?
|
421 |
+
__( 'Core files scanned regularly for hacks', 'wp-simple-firewall' )
|
422 |
+
: __( "Core files are never scanned for hacks!", 'wp-simple-firewall' ),
|
423 |
+
'weight' => 2,
|
424 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'enable_core_file_integrity_scan' ),
|
425 |
+
];
|
426 |
+
if ( $bCore && !$opts->isRepairFileWP() ) {
|
427 |
+
$data[ 'key_opts' ][ 'wcf_repair' ] = [
|
428 |
+
'name' => __( 'WP Core File Repair', 'wp-simple-firewall' ),
|
429 |
+
'enabled' => $opts->isRepairFileWP(),
|
430 |
+
'summary' => $opts->isRepairFileWP() ?
|
431 |
+
__( 'Core files are automatically repaired', 'wp-simple-firewall' )
|
432 |
+
: __( "Core files aren't automatically repaired!", 'wp-simple-firewall' ),
|
433 |
+
'weight' => 1,
|
434 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'file_repair_areas' ),
|
435 |
+
];
|
436 |
+
}
|
437 |
+
|
438 |
+
$bUcf = $mod->getScanCon( 'ufc' )->isEnabled();
|
439 |
+
$data[ 'key_opts' ][ 'ufc' ] = [
|
440 |
+
'name' => __( 'Unrecognised Files', 'wp-simple-firewall' ),
|
441 |
+
'enabled' => $bUcf,
|
442 |
+
'summary' => $bUcf ?
|
443 |
+
__( 'Core directories scanned regularly for unrecognised files', 'wp-simple-firewall' )
|
444 |
+
: __( "WP Core is never scanned for unrecognised files!", 'wp-simple-firewall' ),
|
445 |
+
'weight' => 2,
|
446 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
447 |
+
];
|
448 |
+
if ( $bUcf && !$opts->isUfsDeleteFiles() ) {
|
449 |
+
$data[ 'key_opts' ][ 'ufc_repair' ] = [
|
450 |
+
'name' => __( 'Unrecognised Files Removal', 'wp-simple-firewall' ),
|
451 |
+
'enabled' => $opts->isUfsDeleteFiles(),
|
452 |
+
'summary' => $opts->isUfsDeleteFiles() ?
|
453 |
+
__( 'Unrecognised files are automatically removed', 'wp-simple-firewall' )
|
454 |
+
: __( "Unrecognised files aren't automatically removed!", 'wp-simple-firewall' ),
|
455 |
+
'weight' => 1,
|
456 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
457 |
+
];
|
458 |
+
}
|
459 |
+
|
460 |
+
$bWpv = $mod->getScanCon( 'wpv' )->isEnabled();
|
461 |
+
$data[ 'key_opts' ][ 'wpv' ] = [
|
462 |
+
'name' => __( 'Vulnerability Scan', 'wp-simple-firewall' ),
|
463 |
+
'enabled' => $bWpv,
|
464 |
+
'summary' => $bWpv ?
|
465 |
+
__( 'Regularly scanning for known vulnerabilities', 'wp-simple-firewall' )
|
466 |
+
: __( "Plugins/Themes never scanned for vulnerabilities!", 'wp-simple-firewall' ),
|
467 |
+
'weight' => 2,
|
468 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_wpv' ),
|
469 |
+
];
|
470 |
+
$bWpvAutoUpdates = $opts->isWpvulnAutoupdatesEnabled();
|
471 |
+
if ( $bWpv && !$bWpvAutoUpdates ) {
|
472 |
+
$data[ 'key_opts' ][ 'wpv_repair' ] = [
|
473 |
+
'name' => __( 'Auto Update', 'wp-simple-firewall' ),
|
474 |
+
'enabled' => $bWpvAutoUpdates,
|
475 |
+
'summary' => $bWpvAutoUpdates ?
|
476 |
+
__( 'Vulnerable items are automatically updated', 'wp-simple-firewall' )
|
477 |
+
: __( "Vulnerable items aren't automatically updated!", 'wp-simple-firewall' ),
|
478 |
+
'weight' => 1,
|
479 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_wpv' ),
|
480 |
+
];
|
481 |
+
}
|
482 |
+
|
483 |
+
$bPtg = $mod->getScanCon( 'ptg' )->isEnabled();
|
484 |
+
$data[ 'key_opts' ][ 'ptg' ] = [
|
485 |
+
'title' => $aScanNames[ 'ptg' ],
|
486 |
+
'name' => __( 'Plugin/Theme Guard', 'wp-simple-firewall' ),
|
487 |
+
'enabled' => $bPtg,
|
488 |
+
'summary' => $bPtg ?
|
489 |
+
__( 'Plugins and Themes are guarded against tampering', 'wp-simple-firewall' )
|
490 |
+
: __( "Plugins and Themes are never scanned for tampering!", 'wp-simple-firewall' ),
|
491 |
+
'weight' => 2,
|
492 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'ptg_enable' ),
|
493 |
+
];
|
494 |
+
|
495 |
+
$bMal = $mod->getScanCon( 'mal' )->isEnabled();
|
496 |
+
$data[ 'key_opts' ][ 'mal' ] = [
|
497 |
+
'title' => $aScanNames[ 'mal' ],
|
498 |
+
'name' => $aScanNames[ 'mal' ],
|
499 |
+
'enabled' => $bMal,
|
500 |
+
'summary' => $bMal ?
|
501 |
+
sprintf( __( '%s Scanner is enabled.' ), $aScanNames[ 'mal' ] )
|
502 |
+
: sprintf( __( '%s Scanner is not enabled.' ), $aScanNames[ 'mal' ] ),
|
503 |
+
'weight' => 2,
|
504 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_mal' ),
|
505 |
+
];
|
506 |
+
|
507 |
+
$bApc = $mod->getScanCon( 'apc' )->isEnabled();
|
508 |
+
$data[ 'key_opts' ][ 'apc' ] = [
|
509 |
+
'title' => $aScanNames[ 'apc' ],
|
510 |
+
'name' => $aScanNames[ 'apc' ],
|
511 |
+
'enabled' => $bApc,
|
512 |
+
'summary' => $bApc ?
|
513 |
+
sprintf( __( '%s Scanner is enabled.' ), $aScanNames[ 'apc' ] )
|
514 |
+
: sprintf( __( '%s Scanner is not enabled.' ), $aScanNames[ 'apc' ] ),
|
515 |
+
'weight' => 2,
|
516 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_apc' ),
|
517 |
+
];
|
518 |
+
}
|
519 |
+
|
520 |
+
return $data;
|
521 |
+
}
|
522 |
+
|
523 |
+
/**
|
524 |
+
* @return array
|
525 |
+
*/
|
526 |
+
public function getInsightsNoticesData() {
|
527 |
+
/** @var \ICWP_WPSF_FeatureHandler_HackProtect $mod */
|
528 |
+
$mod = $this->getMod();
|
529 |
+
/** @var Strings $oStrings */
|
530 |
+
$oStrings = $mod->getStrings();
|
531 |
+
$aScanNames = $oStrings->getScanNames();
|
532 |
+
|
533 |
+
$notices = [
|
534 |
+
'title' => __( 'Scans', 'wp-simple-firewall' ),
|
535 |
+
'messages' => []
|
536 |
+
];
|
537 |
+
|
538 |
+
$sScansUrl = $this->getCon()->getModule_Insights()->getUrl_SubInsightsPage( 'scans' );
|
539 |
+
|
540 |
+
{// Malware
|
541 |
+
$scan = $mod->getScanCon( 'mal' );
|
542 |
+
if ( !$scan->isEnabled() ) {
|
543 |
+
$notices[ 'messages' ][ 'mal' ] = [
|
544 |
+
'title' => $aScanNames[ 'mal' ],
|
545 |
+
'message' => sprintf( __( '%s Scanner is not enabled.' ), $aScanNames[ 'mal' ] ),
|
546 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_mal' ),
|
547 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
548 |
+
'rec' => __( 'Automatic detection of Malware is recommended.', 'wp-simple-firewall' )
|
549 |
+
];
|
550 |
+
}
|
551 |
+
elseif ( $scan->getScanHasProblem() ) {
|
552 |
+
$notices[ 'messages' ][ 'mal' ] = [
|
553 |
+
'title' => $aScanNames[ 'mal' ],
|
554 |
+
'message' => __( 'At least 1 file with potential Malware has been discovered.', 'wp-simple-firewall' ),
|
555 |
+
'href' => $sScansUrl,
|
556 |
+
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
557 |
+
'rec' => __( 'Files identified as potential malware should be examined as soon as possible.', 'wp-simple-firewall' )
|
558 |
+
];
|
559 |
+
}
|
560 |
+
}
|
561 |
+
|
562 |
+
{// Core files
|
563 |
+
$scan = $mod->getScanCon( 'wcf' );
|
564 |
+
if ( !$scan->isEnabled() ) {
|
565 |
+
$notices[ 'messages' ][ 'wcf' ] = [
|
566 |
+
'title' => $aScanNames[ 'wcf' ],
|
567 |
+
'message' => __( 'Core File scanner is not enabled.', 'wp-simple-firewall' ),
|
568 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'enable_core_file_integrity_scan' ),
|
569 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
570 |
+
'rec' => __( 'Automatic WordPress Core File scanner should be turned-on.', 'wp-simple-firewall' )
|
571 |
+
];
|
572 |
+
}
|
573 |
+
elseif ( $scan->getScanHasProblem() ) {
|
574 |
+
$notices[ 'messages' ][ 'wcf' ] = [
|
575 |
+
'title' => $aScanNames[ 'wcf' ],
|
576 |
+
'message' => __( 'Modified WordPress core files found.', 'wp-simple-firewall' ),
|
577 |
+
'href' => $sScansUrl,
|
578 |
+
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
579 |
+
'rec' => __( 'Scan WP core files and repair any files that are flagged as modified.', 'wp-simple-firewall' )
|
580 |
+
];
|
581 |
+
}
|
582 |
+
}
|
583 |
+
|
584 |
+
{// Unrecognised
|
585 |
+
$scan = $mod->getScanCon( 'ufc' );
|
586 |
+
if ( !$scan->isEnabled() ) {
|
587 |
+
$notices[ 'messages' ][ 'ufc' ] = [
|
588 |
+
'title' => $aScanNames[ 'ufc' ],
|
589 |
+
'message' => __( 'Unrecognised File scanner is not enabled.', 'wp-simple-firewall' ),
|
590 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_ufc' ),
|
591 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
592 |
+
'rec' => __( 'Automatic scanning for non-WordPress core files is recommended.', 'wp-simple-firewall' )
|
593 |
+
];
|
594 |
+
}
|
595 |
+
elseif ( $scan->getScanHasProblem() ) {
|
596 |
+
$notices[ 'messages' ][ 'ufc' ] = [
|
597 |
+
'title' => $aScanNames[ 'ufc' ],
|
598 |
+
'message' => __( 'Unrecognised files found in WordPress Core directory.', 'wp-simple-firewall' ),
|
599 |
+
'href' => $sScansUrl,
|
600 |
+
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
601 |
+
'rec' => __( 'Scan and remove any files that are not meant to be in the WP core directories.', 'wp-simple-firewall' )
|
602 |
+
];
|
603 |
+
}
|
604 |
+
}
|
605 |
+
|
606 |
+
{// Plugin/Theme Guard
|
607 |
+
$scan = $mod->getScanCon( 'ptg' );
|
608 |
+
if ( !$scan->isEnabled() ) {
|
609 |
+
$notices[ 'messages' ][ 'ptg' ] = [
|
610 |
+
'title' => $aScanNames[ 'ptg' ],
|
611 |
+
'message' => __( 'Automatic Plugin/Themes Guard is not enabled.', 'wp-simple-firewall' ),
|
612 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'ptg_enable' ),
|
613 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
614 |
+
'rec' => __( 'Automatic detection of plugin/theme modifications is recommended.', 'wp-simple-firewall' )
|
615 |
+
];
|
616 |
+
}
|
617 |
+
elseif ( $scan->getScanHasProblem() ) {
|
618 |
+
$notices[ 'messages' ][ 'ptg' ] = [
|
619 |
+
'title' => $aScanNames[ 'ptg' ],
|
620 |
+
'message' => __( 'A plugin/theme was found to have been modified.', 'wp-simple-firewall' ),
|
621 |
+
'href' => $sScansUrl,
|
622 |
+
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
623 |
+
'rec' => __( 'Reviewing modifications to your plugins/themes is recommended.', 'wp-simple-firewall' )
|
624 |
+
];
|
625 |
+
}
|
626 |
+
}
|
627 |
+
|
628 |
+
{// Vulnerability Scanner
|
629 |
+
$scan = $mod->getScanCon( 'wpv' );
|
630 |
+
if ( !$scan->isEnabled() ) {
|
631 |
+
$notices[ 'messages' ][ 'wpv' ] = [
|
632 |
+
'title' => $aScanNames[ 'wpv' ],
|
633 |
+
'message' => __( 'Vulnerability Scanner is not enabled.', 'wp-simple-firewall' ),
|
634 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_wpv' ),
|
635 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
636 |
+
'rec' => __( 'Automatic detection of vulnerabilities is recommended.', 'wp-simple-firewall' )
|
637 |
+
];
|
638 |
+
}
|
639 |
+
elseif ( $scan->getScanHasProblem() ) {
|
640 |
+
$notices[ 'messages' ][ 'wpv' ] = [
|
641 |
+
'title' => $aScanNames[ 'wpv' ],
|
642 |
+
'message' => __( 'At least 1 item has known vulnerabilities.', 'wp-simple-firewall' ),
|
643 |
+
'href' => $sScansUrl,
|
644 |
+
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
645 |
+
'rec' => __( 'Items with known vulnerabilities should be updated, removed, or replaced.', 'wp-simple-firewall' )
|
646 |
+
];
|
647 |
+
}
|
648 |
+
}
|
649 |
+
|
650 |
+
{// Abandoned Plugins
|
651 |
+
$scan = $mod->getScanCon( 'apc' );
|
652 |
+
if ( !$scan->isEnabled() ) {
|
653 |
+
$notices[ 'messages' ][ 'apc' ] = [
|
654 |
+
'title' => $aScanNames[ 'apc' ],
|
655 |
+
'message' => __( 'Abandoned Plugins Scanner is not enabled.', 'wp-simple-firewall' ),
|
656 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_scan_apc' ),
|
657 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
658 |
+
'rec' => __( 'Automatic detection of abandoned plugins is recommended.', 'wp-simple-firewall' )
|
659 |
+
];
|
660 |
+
}
|
661 |
+
elseif ( $scan->getScanHasProblem() ) {
|
662 |
+
$notices[ 'messages' ][ 'apc' ] = [
|
663 |
+
'title' => $aScanNames[ 'apc' ],
|
664 |
+
'message' => __( 'At least 1 plugin on your site is abandoned.', 'wp-simple-firewall' ),
|
665 |
+
'href' => $sScansUrl,
|
666 |
+
'action' => __( 'Run Scan', 'wp-simple-firewall' ),
|
667 |
+
'rec' => __( 'Plugins that have been abandoned represent a potential risk to your site.', 'wp-simple-firewall' )
|
668 |
+
];
|
669 |
+
}
|
670 |
+
}
|
671 |
+
|
672 |
+
return $notices;
|
673 |
+
}
|
674 |
+
|
675 |
+
/**
|
676 |
+
* @param string $section
|
677 |
+
* @return array
|
678 |
+
*/
|
679 |
+
protected function getSectionWarnings( $section ) {
|
680 |
+
$aWarnings = [];
|
681 |
+
|
682 |
+
switch ( $section ) {
|
683 |
+
|
684 |
+
case 'section_realtime':
|
685 |
+
$bCanHandshake = $this->getCon()
|
686 |
+
->getModule_Plugin()
|
687 |
+
->getShieldNetApiController()
|
688 |
+
->canHandshake();
|
689 |
+
if ( !$bCanHandshake ) {
|
690 |
+
$aWarnings[] = sprintf( __( 'Not available as your site cannot handshake with ShieldNET API.', 'wp-simple-firewall' ), 'OpenSSL' );
|
691 |
+
}
|
692 |
+
// if ( !Services::Encrypt()->isSupportedOpenSslDataEncryption() ) {
|
693 |
+
// $aWarnings[] = sprintf( __( 'Not available because the %s extension is not available.', 'wp-simple-firewall' ), 'OpenSSL' );
|
694 |
+
// }
|
695 |
+
// if ( !Services::WpFs()->isFilesystemAccessDirect() ) {
|
696 |
+
// $aWarnings[] = sprintf( __( "Not available because PHP/WordPress doesn't have direct filesystem access.", 'wp-simple-firewall' ), 'OpenSSL' );
|
697 |
+
// }
|
698 |
+
break;
|
699 |
+
}
|
700 |
+
|
701 |
+
return $aWarnings;
|
702 |
+
}
|
703 |
+
}
|
src/lib/src/Modules/Headers/Strings.php
CHANGED
@@ -7,13 +7,13 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
7 |
class Strings extends Base\Strings {
|
8 |
|
9 |
/**
|
10 |
-
* @param string $
|
11 |
* @return array
|
12 |
* @throws \Exception
|
13 |
*/
|
14 |
-
public function getSectionStrings( $
|
15 |
|
16 |
-
switch ( $
|
17 |
|
18 |
case 'section_enable_plugin_feature_headers' :
|
19 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -44,7 +44,7 @@ class Strings extends Base\Strings {
|
|
44 |
break;
|
45 |
|
46 |
default:
|
47 |
-
return parent::getSectionStrings( $
|
48 |
}
|
49 |
|
50 |
return [
|
@@ -55,14 +55,14 @@ class Strings extends Base\Strings {
|
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
-
* @param string $
|
59 |
* @return array
|
60 |
* @throws \Exception
|
61 |
*/
|
62 |
-
public function getOptionStrings( $
|
63 |
$sModName = $this->getMod()->getMainFeatureName();
|
64 |
|
65 |
-
switch ( $
|
66 |
|
67 |
case 'enable_headers' :
|
68 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -149,7 +149,7 @@ class Strings extends Base\Strings {
|
|
149 |
break;
|
150 |
|
151 |
default:
|
152 |
-
return parent::getOptionStrings( $
|
153 |
}
|
154 |
|
155 |
return [
|
7 |
class Strings extends Base\Strings {
|
8 |
|
9 |
/**
|
10 |
+
* @param string $section
|
11 |
* @return array
|
12 |
* @throws \Exception
|
13 |
*/
|
14 |
+
public function getSectionStrings( $section ) {
|
15 |
|
16 |
+
switch ( $section ) {
|
17 |
|
18 |
case 'section_enable_plugin_feature_headers' :
|
19 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
44 |
break;
|
45 |
|
46 |
default:
|
47 |
+
return parent::getSectionStrings( $section );
|
48 |
}
|
49 |
|
50 |
return [
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
+
* @param string $key
|
59 |
* @return array
|
60 |
* @throws \Exception
|
61 |
*/
|
62 |
+
public function getOptionStrings( $key ) {
|
63 |
$sModName = $this->getMod()->getMainFeatureName();
|
64 |
|
65 |
+
switch ( $key ) {
|
66 |
|
67 |
case 'enable_headers' :
|
68 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
149 |
break;
|
150 |
|
151 |
default:
|
152 |
+
return parent::getOptionStrings( $key );
|
153 |
}
|
154 |
|
155 |
return [
|
src/lib/src/Modules/Headers/UI.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Headers;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
|
7 |
+
class UI extends Base\ShieldUI {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getInsightsConfigCardData() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_Headers $mod */
|
14 |
+
$mod = $this->getMod();
|
15 |
+
/** @var Options $opts */
|
16 |
+
$opts = $this->getOptions();
|
17 |
+
|
18 |
+
$data = [
|
19 |
+
'strings' => [
|
20 |
+
'title' => __( 'HTTP Security Headers', 'wp-simple-firewall' ),
|
21 |
+
'sub' => __( 'Protect Visitors With Powerful HTTP Headers', 'wp-simple-firewall' ),
|
22 |
+
],
|
23 |
+
'key_opts' => [],
|
24 |
+
'href_options' => $mod->getUrl_AdminPage()
|
25 |
+
];
|
26 |
+
|
27 |
+
if ( !$mod->isModOptEnabled() ) {
|
28 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$bAllEnabled = $opts->isEnabledXFrame() && $opts->isEnabledXssProtection()
|
32 |
+
&& $opts->isEnabledContentTypeHeader() && $opts->isReferrerPolicyEnabled();
|
33 |
+
$data[ 'key_opts' ][ 'all' ] = [
|
34 |
+
'name' => __( 'HTTP Headers', 'wp-simple-firewall' ),
|
35 |
+
'enabled' => $bAllEnabled,
|
36 |
+
'summary' => $bAllEnabled ?
|
37 |
+
__( 'All important security Headers have been set', 'wp-simple-firewall' )
|
38 |
+
: __( "At least one of the HTTP Headers hasn't been set", 'wp-simple-firewall' ),
|
39 |
+
'weight' => 2,
|
40 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_security_headers' ),
|
41 |
+
];
|
42 |
+
$bCsp = $opts->isEnabledContentSecurityPolicy();
|
43 |
+
$data[ 'key_opts' ][ 'csp' ] = [
|
44 |
+
'name' => __( 'Content Security Policies', 'wp-simple-firewall' ),
|
45 |
+
'enabled' => $bCsp,
|
46 |
+
'summary' => $bCsp ?
|
47 |
+
__( 'Content Security Policy is turned on', 'wp-simple-firewall' )
|
48 |
+
: __( "Content Security Policies aren't active", 'wp-simple-firewall' ),
|
49 |
+
'weight' => 1,
|
50 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_content_security_policy' ),
|
51 |
+
];
|
52 |
+
}
|
53 |
+
|
54 |
+
return $data;
|
55 |
+
}
|
56 |
+
}
|
src/lib/src/Modules/IPs/AjaxHandler.php
CHANGED
@@ -8,12 +8,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
-
* @param string $
|
12 |
* @return array
|
13 |
*/
|
14 |
-
protected function processAjaxAction( $
|
15 |
|
16 |
-
switch ( $
|
17 |
case 'ip_insert':
|
18 |
$aResponse = $this->ajaxExec_AddIp();
|
19 |
break;
|
@@ -27,7 +27,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
27 |
break;
|
28 |
|
29 |
default:
|
30 |
-
$aResponse = parent::processAjaxAction( $
|
31 |
}
|
32 |
|
33 |
return $aResponse;
|
@@ -37,8 +37,8 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
37 |
* @return array
|
38 |
*/
|
39 |
private function ajaxExec_AddIp() {
|
40 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
41 |
-
$
|
42 |
$oIpServ = Services::IP();
|
43 |
|
44 |
$aFormParams = $this->getAjaxFormParams();
|
@@ -53,7 +53,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
53 |
|| $oIpServ->isValidIp4Range( $sIp )
|
54 |
|| $oIpServ->isValidIp6Range( $sIp );
|
55 |
|
56 |
-
$bIsBlackList = $sList != $
|
57 |
|
58 |
// TODO: Bring this IP verification out of here and make it more accessible
|
59 |
if ( empty( $sIp ) ) {
|
@@ -65,7 +65,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
65 |
elseif ( !$bAcceptableIp ) {
|
66 |
$sMessage = __( "IP address isn't either a valid IP or a CIDR range", 'wp-simple-firewall' );
|
67 |
}
|
68 |
-
elseif ( $bIsBlackList && !$
|
69 |
$sMessage = __( "Please upgrade to Pro if you'd like to add IPs to the black list manually.", 'wp-simple-firewall' );
|
70 |
}
|
71 |
elseif ( $bIsBlackList && $oIpServ->checkIp( $oIpServ->getRequestIp(), $sIp ) ) {
|
@@ -78,10 +78,10 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
78 |
$sLabel = isset( $aFormParams[ 'label' ] ) ? $aFormParams[ 'label' ] : '';
|
79 |
$oIP = null;
|
80 |
switch ( $sList ) {
|
81 |
-
case $
|
82 |
try {
|
83 |
$oIP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
84 |
-
->setMod( $
|
85 |
->setIP( $sIp )
|
86 |
->toManualWhitelist( $sLabel );
|
87 |
}
|
@@ -89,10 +89,10 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
89 |
}
|
90 |
break;
|
91 |
|
92 |
-
case $
|
93 |
try {
|
94 |
$oIP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
95 |
-
->setMod( $
|
96 |
->setIP( $sIp )
|
97 |
->toManualBlacklist( $sLabel );
|
98 |
}
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
+
* @param string $action
|
12 |
* @return array
|
13 |
*/
|
14 |
+
protected function processAjaxAction( $action ) {
|
15 |
|
16 |
+
switch ( $action ) {
|
17 |
case 'ip_insert':
|
18 |
$aResponse = $this->ajaxExec_AddIp();
|
19 |
break;
|
27 |
break;
|
28 |
|
29 |
default:
|
30 |
+
$aResponse = parent::processAjaxAction( $action );
|
31 |
}
|
32 |
|
33 |
return $aResponse;
|
37 |
* @return array
|
38 |
*/
|
39 |
private function ajaxExec_AddIp() {
|
40 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
41 |
+
$mod = $this->getMod();
|
42 |
$oIpServ = Services::IP();
|
43 |
|
44 |
$aFormParams = $this->getAjaxFormParams();
|
53 |
|| $oIpServ->isValidIp4Range( $sIp )
|
54 |
|| $oIpServ->isValidIp6Range( $sIp );
|
55 |
|
56 |
+
$bIsBlackList = $sList != $mod::LIST_MANUAL_WHITE;
|
57 |
|
58 |
// TODO: Bring this IP verification out of here and make it more accessible
|
59 |
if ( empty( $sIp ) ) {
|
65 |
elseif ( !$bAcceptableIp ) {
|
66 |
$sMessage = __( "IP address isn't either a valid IP or a CIDR range", 'wp-simple-firewall' );
|
67 |
}
|
68 |
+
elseif ( $bIsBlackList && !$mod->isPremium() ) {
|
69 |
$sMessage = __( "Please upgrade to Pro if you'd like to add IPs to the black list manually.", 'wp-simple-firewall' );
|
70 |
}
|
71 |
elseif ( $bIsBlackList && $oIpServ->checkIp( $oIpServ->getRequestIp(), $sIp ) ) {
|
78 |
$sLabel = isset( $aFormParams[ 'label' ] ) ? $aFormParams[ 'label' ] : '';
|
79 |
$oIP = null;
|
80 |
switch ( $sList ) {
|
81 |
+
case $mod::LIST_MANUAL_WHITE:
|
82 |
try {
|
83 |
$oIP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
84 |
+
->setMod( $mod )
|
85 |
->setIP( $sIp )
|
86 |
->toManualWhitelist( $sLabel );
|
87 |
}
|
89 |
}
|
90 |
break;
|
91 |
|
92 |
+
case $mod::LIST_MANUAL_BLACK:
|
93 |
try {
|
94 |
$oIP = ( new Shield\Modules\IPs\Lib\Ops\AddIp() )
|
95 |
+
->setMod( $mod )
|
96 |
->setIP( $sIp )
|
97 |
->toManualBlacklist( $sLabel );
|
98 |
}
|
src/lib/src/Modules/IPs/BotTrack/TrackLinkCheese.php
CHANGED
@@ -30,28 +30,27 @@ class TrackLinkCheese extends Base {
|
|
30 |
$sTempl = Services::WpGeneral()->isPermalinksEnabled() ? "Disallow: /%s-*/\n" : "Disallow: /*?*%s=\n";
|
31 |
$sRobotsText = rtrim( $sRobotsText, "\n" )."\n";
|
32 |
foreach ( $this->getPossibleWords() as $sWord ) {
|
33 |
-
$sRobotsText .= sprintf( $sTempl, $this->
|
34 |
}
|
35 |
return $sRobotsText;
|
36 |
}
|
37 |
|
38 |
private function isCheese() {
|
39 |
-
|
40 |
-
$
|
41 |
-
$oReq = Services::Request();
|
42 |
|
43 |
$bIsCheese = false;
|
44 |
if ( Services::WpGeneral()->isPermalinksEnabled() ) {
|
45 |
preg_match(
|
46 |
-
sprintf( '#^%s-(%s)-([a-z0-9]{7,9})$#i', $
|
47 |
-
trim( $
|
48 |
$aMatches
|
49 |
);
|
50 |
$bIsCheese = isset( $aMatches[ 2 ] );
|
51 |
}
|
52 |
else {
|
53 |
foreach ( $this->getPossibleWords() as $sWord ) {
|
54 |
-
if ( preg_match( '#^[a-z0-9]{7,9}$#i', $
|
55 |
$bIsCheese = true;
|
56 |
break;
|
57 |
}
|
@@ -74,17 +73,16 @@ class TrackLinkCheese extends Base {
|
|
74 |
* @return string
|
75 |
*/
|
76 |
private function buildTrapHref() {
|
77 |
-
|
78 |
-
$oFO = $this->getMod();
|
79 |
|
80 |
-
$
|
81 |
$sKey = substr( md5( wp_generate_password() ), 5, rand( 7, 9 ) );
|
82 |
$sWord = $this->getPossibleWords()[ rand( 1, count( $this->getPossibleWords() ) ) - 1 ];
|
83 |
-
if ( $
|
84 |
-
$sLink = $
|
85 |
}
|
86 |
else {
|
87 |
-
$sLink = add_query_arg( [ $
|
88 |
}
|
89 |
return $sLink;
|
90 |
}
|
30 |
$sTempl = Services::WpGeneral()->isPermalinksEnabled() ? "Disallow: /%s-*/\n" : "Disallow: /*?*%s=\n";
|
31 |
$sRobotsText = rtrim( $sRobotsText, "\n" )."\n";
|
32 |
foreach ( $this->getPossibleWords() as $sWord ) {
|
33 |
+
$sRobotsText .= sprintf( $sTempl, $this->getCon()->prefix( $sWord ) );
|
34 |
}
|
35 |
return $sRobotsText;
|
36 |
}
|
37 |
|
38 |
private function isCheese() {
|
39 |
+
$con = $this->getCon();
|
40 |
+
$req = Services::Request();
|
|
|
41 |
|
42 |
$bIsCheese = false;
|
43 |
if ( Services::WpGeneral()->isPermalinksEnabled() ) {
|
44 |
preg_match(
|
45 |
+
sprintf( '#^%s-(%s)-([a-z0-9]{7,9})$#i', $con->prefix(), implode( '|', $this->getPossibleWords() ) ),
|
46 |
+
trim( $req->getPath(), '/' ),
|
47 |
$aMatches
|
48 |
);
|
49 |
$bIsCheese = isset( $aMatches[ 2 ] );
|
50 |
}
|
51 |
else {
|
52 |
foreach ( $this->getPossibleWords() as $sWord ) {
|
53 |
+
if ( preg_match( '#^[a-z0-9]{7,9}$#i', $req->query( $con->prefix( $sWord ) ) ) ) {
|
54 |
$bIsCheese = true;
|
55 |
break;
|
56 |
}
|
73 |
* @return string
|
74 |
*/
|
75 |
private function buildTrapHref() {
|
76 |
+
$con = $this->getCon();
|
|
|
77 |
|
78 |
+
$oWP = Services::WpGeneral();
|
79 |
$sKey = substr( md5( wp_generate_password() ), 5, rand( 7, 9 ) );
|
80 |
$sWord = $this->getPossibleWords()[ rand( 1, count( $this->getPossibleWords() ) ) - 1 ];
|
81 |
+
if ( $oWP->isPermalinksEnabled() ) {
|
82 |
+
$sLink = $oWP->getHomeUrl( sprintf( '/%s-%s/', $con->prefix( $sWord ), $sKey ) );
|
83 |
}
|
84 |
else {
|
85 |
+
$sLink = add_query_arg( [ $con->prefix( $sWord ) => $sKey ], $oWP->getHomeUrl() );
|
86 |
}
|
87 |
return $sLink;
|
88 |
}
|
src/lib/src/Modules/IPs/BotTrack/TrackLoginFailed.php
CHANGED
@@ -29,7 +29,7 @@ class TrackLoginFailed extends Base {
|
|
29 |
|
30 |
// Adds an extra message to login failed
|
31 |
$oUser->add(
|
32 |
-
$this->
|
33 |
$this->getMod()->getTextOpt( 'text_loginfailed' )
|
34 |
);
|
35 |
}
|
29 |
|
30 |
// Adds an extra message to login failed
|
31 |
$oUser->add(
|
32 |
+
$this->getCon()->prefix( 'transgression-warning' ),
|
33 |
$this->getMod()->getTextOpt( 'text_loginfailed' )
|
34 |
);
|
35 |
}
|
src/lib/src/Modules/IPs/Components/ProcessOffense.php
CHANGED
@@ -16,18 +16,16 @@ class ProcessOffense {
|
|
16 |
use Shield\Modules\ModConsumer;
|
17 |
use IpAddressConsumer;
|
18 |
|
19 |
-
/**
|
20 |
-
*/
|
21 |
public function run() {
|
22 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
23 |
-
$
|
24 |
-
$
|
25 |
-
/** @var IPs\Options $
|
26 |
-
$
|
27 |
|
28 |
try {
|
29 |
$oIP = ( new IPs\Lib\Ops\AddIp() )
|
30 |
-
->setMod( $
|
31 |
->setIP( $this->getIP() )
|
32 |
->toAutoBlacklist();
|
33 |
}
|
@@ -38,16 +36,16 @@ class ProcessOffense {
|
|
38 |
if ( $oIP instanceof Databases\IPs\EntryVO ) {
|
39 |
$nCurrent = $oIP->transgressions;
|
40 |
|
41 |
-
$oTracker = $
|
42 |
$nNewTotal = $oIP->transgressions + $oTracker->getOffenseCount();
|
43 |
$bToBlock = $oTracker->isBlocked() ||
|
44 |
-
( $oIP->blocked_at == 0 && ( $nNewTotal >= $
|
45 |
|
46 |
/** @var Databases\IPs\Update $oUp */
|
47 |
-
$oUp = $
|
48 |
$oUp->updateTransgressions( $oIP, $nNewTotal );
|
49 |
|
50 |
-
$
|
51 |
[
|
52 |
'audit' => [
|
53 |
'from' => $nCurrent,
|
@@ -62,9 +60,9 @@ class ProcessOffense {
|
|
62 |
* so we fire ip_offense but suppress the audit
|
63 |
*/
|
64 |
if ( $bToBlock ) {
|
65 |
-
$oUp = $
|
66 |
$oUp->setBlocked( $oIP );
|
67 |
-
$
|
68 |
}
|
69 |
}
|
70 |
}
|
16 |
use Shield\Modules\ModConsumer;
|
17 |
use IpAddressConsumer;
|
18 |
|
|
|
|
|
19 |
public function run() {
|
20 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
21 |
+
$mod = $this->getMod();
|
22 |
+
$con = $this->getCon();
|
23 |
+
/** @var IPs\Options $opts */
|
24 |
+
$opts = $this->getOptions();
|
25 |
|
26 |
try {
|
27 |
$oIP = ( new IPs\Lib\Ops\AddIp() )
|
28 |
+
->setMod( $mod )
|
29 |
->setIP( $this->getIP() )
|
30 |
->toAutoBlacklist();
|
31 |
}
|
36 |
if ( $oIP instanceof Databases\IPs\EntryVO ) {
|
37 |
$nCurrent = $oIP->transgressions;
|
38 |
|
39 |
+
$oTracker = $mod->loadOffenseTracker();
|
40 |
$nNewTotal = $oIP->transgressions + $oTracker->getOffenseCount();
|
41 |
$bToBlock = $oTracker->isBlocked() ||
|
42 |
+
( $oIP->blocked_at == 0 && ( $nNewTotal >= $opts->getOffenseLimit() ) );
|
43 |
|
44 |
/** @var Databases\IPs\Update $oUp */
|
45 |
+
$oUp = $mod->getDbHandler_IPs()->getQueryUpdater();
|
46 |
$oUp->updateTransgressions( $oIP, $nNewTotal );
|
47 |
|
48 |
+
$con->fireEvent( $bToBlock ? 'ip_blocked' : 'ip_offense',
|
49 |
[
|
50 |
'audit' => [
|
51 |
'from' => $nCurrent,
|
60 |
* so we fire ip_offense but suppress the audit
|
61 |
*/
|
62 |
if ( $bToBlock ) {
|
63 |
+
$oUp = $mod->getDbHandler_IPs()->getQueryUpdater();
|
64 |
$oUp->setBlocked( $oIP );
|
65 |
+
$con->fireEvent( 'ip_offense', [ 'suppress_audit' => true ] );
|
66 |
}
|
67 |
}
|
68 |
}
|
src/lib/src/Modules/IPs/Components/UnblockIpByMagicLink.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class UnblockIpByMagicLink {
|
10 |
+
|
11 |
+
use Shield\Modules\ModConsumer;
|
12 |
+
|
13 |
+
public function run() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
15 |
+
$oMod = $this->getMod();
|
16 |
+
$oFS = Services::WpFs();
|
17 |
+
|
18 |
+
$sPathUnblockFlag = $oFS->findFileInDir( 'unblock', $this->getCon()->getPath_Flags() );
|
19 |
+
if ( $oFS->isFile( $sPathUnblockFlag ) ) {
|
20 |
+
$sContent = $oFS->getFileContent( $sPathUnblockFlag );
|
21 |
+
if ( !empty( $sContent ) ) {
|
22 |
+
|
23 |
+
$aLines = array_map( 'trim', explode( "\n", $sContent ) );
|
24 |
+
foreach ( $aLines as $sIp ) {
|
25 |
+
$bRemoved = ( new IPs\Lib\Ops\DeleteIp() )
|
26 |
+
->setDbHandler( $oMod->getDbHandler_IPs() )
|
27 |
+
->setIP( $sIp )
|
28 |
+
->fromBlacklist();
|
29 |
+
if ( $bRemoved ) {
|
30 |
+
$this->getCon()->fireEvent( 'ip_unblock_flag', [ 'audit' => [ 'ip' => $sIp ] ] );
|
31 |
+
}
|
32 |
+
}
|
33 |
+
}
|
34 |
+
$oFS->deleteFile( $sPathUnblockFlag );
|
35 |
+
}
|
36 |
+
}
|
37 |
+
}
|
src/lib/src/Modules/IPs/Lib/AutoUnblock.php
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class AutoUnblock {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* This should only be run if the current IP has been verified as being blocked
|
15 |
+
* @return bool - true if IP is unblocked, false otherwise.
|
16 |
+
*/
|
17 |
+
public function run() {
|
18 |
+
try {
|
19 |
+
$bUnblocked = $this->processAutoUnblockRequest();
|
20 |
+
}
|
21 |
+
catch ( \Exception $oE ) {
|
22 |
+
$bUnblocked = false;
|
23 |
+
}
|
24 |
+
if ( !$bUnblocked ) {
|
25 |
+
try {
|
26 |
+
$bUnblocked = $this->processUserMagicLink();
|
27 |
+
}
|
28 |
+
catch ( \Exception $oE ) {
|
29 |
+
}
|
30 |
+
}
|
31 |
+
return $bUnblocked;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return bool
|
36 |
+
* @throws \Exception
|
37 |
+
*/
|
38 |
+
private function processAutoUnblockRequest() {
|
39 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
40 |
+
$mod = $this->getMod();
|
41 |
+
/** @var IPs\Options $opts */
|
42 |
+
$opts = $this->getOptions();
|
43 |
+
$req = Services::Request();
|
44 |
+
|
45 |
+
$unblocked = false;
|
46 |
+
|
47 |
+
if ( $opts->isEnabledAutoVisitorRecover() && $req->isPost()
|
48 |
+
&& $req->request( 'action' ) == $mod->prefix() && $req->request( 'exec' ) == 'uau' ) {
|
49 |
+
|
50 |
+
if ( check_admin_referer( $req->request( 'exec' ), 'exec_nonce' ) !== 1 ) {
|
51 |
+
throw new \Exception( 'Nonce failed' );
|
52 |
+
}
|
53 |
+
if ( strlen( $req->post( 'icwp_wpsf_login_email' ) ) > 0 ) {
|
54 |
+
throw new \Exception( 'Email should not be provided in honeypot' );
|
55 |
+
}
|
56 |
+
|
57 |
+
$sIP = Services::IP()->getRequestIp();
|
58 |
+
if ( $req->post( 'ip' ) != $sIP ) {
|
59 |
+
throw new \Exception( 'IP does not match' );
|
60 |
+
}
|
61 |
+
|
62 |
+
$oLoginMod = $this->getCon()->getModule_LoginGuard();
|
63 |
+
$sGasp = $req->post( $oLoginMod->getGaspKey() );
|
64 |
+
if ( empty( $sGasp ) ) {
|
65 |
+
throw new \Exception( 'GASP failed' );
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( !$opts->getCanIpRequestAutoUnblock( $sIP ) ) {
|
69 |
+
throw new \Exception( 'IP already processed in the last 24hrs' );
|
70 |
+
}
|
71 |
+
|
72 |
+
{
|
73 |
+
$aExistingIps = $opts->getAutoUnblockIps();
|
74 |
+
$aExistingIps[ $sIP ] = Services::Request()->ts();
|
75 |
+
$opts->setOpt( 'autounblock_ips',
|
76 |
+
array_filter( $aExistingIps, function ( $nTS ) {
|
77 |
+
return Services::Request()
|
78 |
+
->carbon()
|
79 |
+
->subDays( 1 )->timestamp < $nTS;
|
80 |
+
} )
|
81 |
+
);
|
82 |
+
}
|
83 |
+
|
84 |
+
( new IPs\Lib\Ops\DeleteIp() )
|
85 |
+
->setDbHandler( $mod->getDbHandler_IPs() )
|
86 |
+
->setIP( $sIP )
|
87 |
+
->fromBlacklist();
|
88 |
+
$unblocked = true;
|
89 |
+
}
|
90 |
+
|
91 |
+
return $unblocked;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return bool
|
96 |
+
* @throws \Exception
|
97 |
+
*/
|
98 |
+
private function processUserMagicLink() {
|
99 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
100 |
+
$mod = $this->getMod();
|
101 |
+
/** @var IPs\Options $opts */
|
102 |
+
$opts = $this->getOptions();
|
103 |
+
$req = Services::Request();
|
104 |
+
|
105 |
+
$unblocked = false;
|
106 |
+
|
107 |
+
if ( $opts->isEnabledMagicEmailLinkRecover()
|
108 |
+
&& $req->query( 'action' ) == $mod->prefix()
|
109 |
+
&& strpos( $req->query( 'exec' ), 'uaum-' ) === 0 ) {
|
110 |
+
|
111 |
+
if ( check_admin_referer( $req->request( 'exec' ), 'exec_nonce' ) !== 1 ) {
|
112 |
+
throw new \Exception( 'Nonce failed' );
|
113 |
+
}
|
114 |
+
|
115 |
+
$user = Services::WpUsers()->getCurrentWpUser();
|
116 |
+
if ( !$user instanceof \WP_User ) {
|
117 |
+
throw new \Exception( 'There is no user currently logged-in.' );
|
118 |
+
}
|
119 |
+
|
120 |
+
$linkParts = explode( '-', $req->query( 'exec' ), 3 );
|
121 |
+
|
122 |
+
if ( !hash_equals( substr( sha1( $user->user_login ), 0, 6 ), $linkParts[ 2 ] ) ) {
|
123 |
+
throw new \Exception( 'Users do not match.' );
|
124 |
+
}
|
125 |
+
|
126 |
+
if ( $req->query( 'ip' ) !== Services::IP()->getRequestIp() ) {
|
127 |
+
throw new \Exception( 'IP does not match.' );
|
128 |
+
}
|
129 |
+
|
130 |
+
if ( $linkParts[ 1 ] === 'init' ) {
|
131 |
+
if ( !$opts->getCanRequestAutoUnblockEmailLink( $user ) ) {
|
132 |
+
throw new \Exception( 'User already processed recently.' );
|
133 |
+
}
|
134 |
+
|
135 |
+
$this->sendMagicLinkEmail();
|
136 |
+
{
|
137 |
+
$existing = $opts->getAutoUnblockEmailIDs();
|
138 |
+
$existing[ $user->ID ] = Services::Request()->ts();
|
139 |
+
$opts->setOpt( 'autounblock_emailids',
|
140 |
+
array_filter( $existing, function ( $nTS ) {
|
141 |
+
return Services::Request()
|
142 |
+
->carbon()
|
143 |
+
->subHours( 1 )->timestamp < $nTS;
|
144 |
+
} )
|
145 |
+
);
|
146 |
+
}
|
147 |
+
wp_die( 'Email sent.' );
|
148 |
+
}
|
149 |
+
elseif ( $linkParts[ 1 ] === 'go' ) {
|
150 |
+
( new IPs\Lib\Ops\DeleteIp() )
|
151 |
+
->setDbHandler( $mod->getDbHandler_IPs() )
|
152 |
+
->setIP( Services::IP()->getRequestIp() )
|
153 |
+
->fromBlacklist();
|
154 |
+
$unblocked = true;
|
155 |
+
}
|
156 |
+
else {
|
157 |
+
throw new \Exception( 'Not a supported UAUM action.' );
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
return $unblocked;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @throws \Exception
|
166 |
+
*/
|
167 |
+
private function sendMagicLinkEmail() {
|
168 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
169 |
+
$mod = $this->getMod();
|
170 |
+
$user = Services::WpUsers()->getCurrentWpUser();
|
171 |
+
|
172 |
+
$mod->getEmailProcessor()
|
173 |
+
->sendEmailWithTemplate(
|
174 |
+
'/email/uaum_init',
|
175 |
+
$user->user_email,
|
176 |
+
__( 'Automatic IP Unblock Request', 'wp-simple-firewall' ),
|
177 |
+
[
|
178 |
+
'flags' => [
|
179 |
+
'show_login_link' => !$this->getCon()->isRelabelled()
|
180 |
+
],
|
181 |
+
'vars' => [
|
182 |
+
],
|
183 |
+
'hrefs' => [
|
184 |
+
'unblock' => add_query_arg(
|
185 |
+
array_merge(
|
186 |
+
$mod->getNonceActionData( 'uaum-go-'.substr( sha1( $user->user_login ), 0, 6 ) ),
|
187 |
+
[
|
188 |
+
'ip' => Services::IP()->getRequestIp()
|
189 |
+
]
|
190 |
+
),
|
191 |
+
Services::WpGeneral()->getHomeUrl()
|
192 |
+
)
|
193 |
+
],
|
194 |
+
'strings' => [
|
195 |
+
'looks_like' => __( "It looks like you've been blocked and have clicked to have your IP address removed from the blocklist.", 'wp-simple-firewall' ),
|
196 |
+
'please_click' => __( 'Please click the link provided below to do so.', 'wp-simple-firewall' ),
|
197 |
+
'details' => __( 'Details', 'wp-simple-firewall' ),
|
198 |
+
'unblock_my_ip' => sprintf( '%s: %s',
|
199 |
+
__( 'Unblock My IP', 'wp-simple-firewall' ), Services::IP()->getRequestIp() ),
|
200 |
+
'or_copy' => __( 'Or Copy-Paste', 'wp-simple-firewall' ),
|
201 |
+
'details_url' => sprintf( '%s: %s',
|
202 |
+
__( 'URL', 'wp-simple-firewall' ), Services::WpGeneral()->getHomeUrl() ),
|
203 |
+
'details_username' => sprintf( '%s: %s', __( 'Username', 'wp-simple-firewall' ), $user->user_login ),
|
204 |
+
'details_ip' => sprintf( '%s: %s', __( 'IP Address', 'wp-simple-firewall' ), Services::IP()
|
205 |
+
->getRequestIp() ),
|
206 |
+
'important' => __( 'Important', 'wp-simple-firewall' ),
|
207 |
+
'imp_limit' => __( "You'll need to wait for a further 60 minutes if your IP address gets blocked again.", 'wp-simple-firewall' ),
|
208 |
+
'imp_browser' => __( "This link will ONLY work if it opens in the same web browser that you used to request this email.", 'wp-simple-firewall' ),
|
209 |
+
]
|
210 |
+
]
|
211 |
+
);
|
212 |
+
}
|
213 |
+
}
|
src/lib/src/Modules/IPs/Lib/BlacklistHandler.php
CHANGED
@@ -12,8 +12,8 @@ class BlacklistHandler {
|
|
12 |
use Modules\Base\OneTimeExecute;
|
13 |
|
14 |
protected function run() {
|
15 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
16 |
-
$
|
17 |
/** @var IPs\Options $oOpts */
|
18 |
$oOpts = $this->getOptions();
|
19 |
if ( $oOpts->isEnabledAutoBlackList() ) {
|
@@ -24,62 +24,68 @@ class BlacklistHandler {
|
|
24 |
}
|
25 |
|
26 |
( new IPs\Components\UnblockIpByFlag() )
|
27 |
-
->setMod( $
|
28 |
->run();
|
29 |
|
30 |
add_action( 'init', [ $this, 'loadBotDetectors' ] ); // hook in the bot detection
|
31 |
|
32 |
-
if ( !$
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
( new
|
37 |
-
->setMod( $
|
38 |
->run();
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
}
|
41 |
}
|
42 |
|
43 |
public function loadBotDetectors() {
|
44 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
45 |
-
$
|
46 |
-
/** @var IPs\Options $
|
47 |
-
$
|
48 |
|
49 |
if ( !Services::WpUsers()->isUserLoggedIn() ) {
|
50 |
|
51 |
-
if ( !$
|
52 |
-
if ( $
|
53 |
( new IPs\BotTrack\TrackXmlRpc() )
|
54 |
-
->setMod( $
|
55 |
->run();
|
56 |
}
|
57 |
-
if ( $
|
58 |
( new IPs\BotTrack\Track404() )
|
59 |
-
->setMod( $
|
60 |
->run();
|
61 |
}
|
62 |
-
if ( $
|
63 |
( new IPs\BotTrack\TrackLoginFailed() )
|
64 |
-
->setMod( $
|
65 |
->run();
|
66 |
}
|
67 |
-
if ( $
|
68 |
( new IPs\BotTrack\TrackLoginInvalid() )
|
69 |
-
->setMod( $
|
70 |
->run();
|
71 |
}
|
72 |
-
if ( $
|
73 |
( new IPs\BotTrack\TrackFakeWebCrawler() )
|
74 |
-
->setMod( $
|
75 |
->run();
|
76 |
}
|
77 |
}
|
78 |
|
79 |
/** Always run link cheese regardless of the verified bot or not */
|
80 |
-
if ( $
|
81 |
( new IPs\BotTrack\TrackLinkCheese() )
|
82 |
-
->setMod( $
|
83 |
->run();
|
84 |
}
|
85 |
}
|
12 |
use Modules\Base\OneTimeExecute;
|
13 |
|
14 |
protected function run() {
|
15 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
16 |
+
$mod = $this->getMod();
|
17 |
/** @var IPs\Options $oOpts */
|
18 |
$oOpts = $this->getOptions();
|
19 |
if ( $oOpts->isEnabledAutoBlackList() ) {
|
24 |
}
|
25 |
|
26 |
( new IPs\Components\UnblockIpByFlag() )
|
27 |
+
->setMod( $mod )
|
28 |
->run();
|
29 |
|
30 |
add_action( 'init', [ $this, 'loadBotDetectors' ] ); // hook in the bot detection
|
31 |
|
32 |
+
if ( !$mod->isVisitorWhitelisted()
|
33 |
+
&& !$this->isRequestWhitelisted() && !$mod->isVerifiedBot() ) {
|
34 |
+
|
35 |
+
// We setup offenses processing immediately but run the blocks on 'init
|
36 |
+
( new ProcessOffenses() )
|
37 |
+
->setMod( $this->getMod() )
|
38 |
->run();
|
39 |
+
add_action( 'init', function () {
|
40 |
+
( new BlockRequest() )
|
41 |
+
->setMod( $this->getMod() )
|
42 |
+
->run();
|
43 |
+
}, -100000 );
|
44 |
+
|
45 |
}
|
46 |
}
|
47 |
}
|
48 |
|
49 |
public function loadBotDetectors() {
|
50 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
51 |
+
$mod = $this->getMod();
|
52 |
+
/** @var IPs\Options $opts */
|
53 |
+
$opts = $this->getOptions();
|
54 |
|
55 |
if ( !Services::WpUsers()->isUserLoggedIn() ) {
|
56 |
|
57 |
+
if ( !$mod->isVerifiedBot() ) {
|
58 |
+
if ( $opts->isEnabledTrackXmlRpc() ) {
|
59 |
( new IPs\BotTrack\TrackXmlRpc() )
|
60 |
+
->setMod( $mod )
|
61 |
->run();
|
62 |
}
|
63 |
+
if ( $opts->isEnabledTrack404() ) {
|
64 |
( new IPs\BotTrack\Track404() )
|
65 |
+
->setMod( $mod )
|
66 |
->run();
|
67 |
}
|
68 |
+
if ( $opts->isEnabledTrackLoginFailed() ) {
|
69 |
( new IPs\BotTrack\TrackLoginFailed() )
|
70 |
+
->setMod( $mod )
|
71 |
->run();
|
72 |
}
|
73 |
+
if ( $opts->isEnabledTrackLoginInvalid() ) {
|
74 |
( new IPs\BotTrack\TrackLoginInvalid() )
|
75 |
+
->setMod( $mod )
|
76 |
->run();
|
77 |
}
|
78 |
+
if ( $opts->isEnabledTrackFakeWebCrawler() ) {
|
79 |
( new IPs\BotTrack\TrackFakeWebCrawler() )
|
80 |
+
->setMod( $mod )
|
81 |
->run();
|
82 |
}
|
83 |
}
|
84 |
|
85 |
/** Always run link cheese regardless of the verified bot or not */
|
86 |
+
if ( $opts->isEnabledTrackLinkCheese() ) {
|
87 |
( new IPs\BotTrack\TrackLinkCheese() )
|
88 |
+
->setMod( $mod )
|
89 |
->run();
|
90 |
}
|
91 |
}
|
src/lib/src/Modules/IPs/Lib/BlockRequest.php
CHANGED
@@ -5,111 +5,79 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib;
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
|
|
8 |
|
9 |
class BlockRequest {
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
13 |
public function run() {
|
14 |
-
|
15 |
-
$oMod = $this->getMod();
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
|
22 |
-
if ( $bIpBlocked ) {
|
23 |
// don't log killed requests
|
24 |
add_filter( $this->getCon()->prefix( 'is_log_traffic' ), '__return_false' );
|
25 |
-
try {
|
26 |
-
if ( $this->processAutoUnblockRequest() ) {
|
27 |
-
return;
|
28 |
-
}
|
29 |
-
}
|
30 |
-
catch ( \Exception $oE ) {
|
31 |
-
}
|
32 |
$this->getCon()->fireEvent( 'conn_kill' );
|
33 |
$this->renderKillPage();
|
34 |
}
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
-
* @
|
39 |
*/
|
40 |
-
private function
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
if ( $oOpts->isEnabledAutoUserRecover() && $oReq->isPost()
|
48 |
-
&& $oReq->request( 'action' ) == $oMod->prefix() && $oReq->request( 'exec' ) == 'uau' ) {
|
49 |
-
|
50 |
-
if ( check_admin_referer( $oReq->request( 'exec' ), 'exec_nonce' ) !== 1 ) {
|
51 |
-
throw new \Exception( 'Nonce failed' );
|
52 |
-
}
|
53 |
-
if ( strlen( $oReq->post( 'icwp_wpsf_login_email' ) ) > 0 ) {
|
54 |
-
throw new \Exception( 'Email should not be provided in honeypot' );
|
55 |
-
}
|
56 |
-
|
57 |
-
$sIp = Services::IP()->getRequestIp();
|
58 |
-
if ( $oReq->post( 'ip' ) != $sIp ) {
|
59 |
-
throw new \Exception( 'IP does not match' );
|
60 |
-
}
|
61 |
-
|
62 |
-
$oLoginMod = $this->getCon()->getModule_LoginGuard();
|
63 |
-
$sGasp = $oReq->post( $oLoginMod->getGaspKey() );
|
64 |
-
if ( empty( $sGasp ) ) {
|
65 |
-
throw new \Exception( 'GASP failed' );
|
66 |
-
}
|
67 |
-
|
68 |
-
if ( !$oOpts->getCanIpRequestAutoUnblock( $sIp ) ) {
|
69 |
-
throw new \Exception( 'IP already processed in the last 24hrs' );
|
70 |
-
}
|
71 |
-
|
72 |
-
{
|
73 |
-
$aExistingIps = $oOpts->getAutoUnblockIps();
|
74 |
-
$aExistingIps[ $sIp ] = Services::Request()->ts();
|
75 |
-
$oOpts->setOpt( 'autounblock_ips', $aExistingIps );
|
76 |
-
}
|
77 |
-
|
78 |
-
( new IPs\Lib\Ops\DeleteIp() )
|
79 |
-
->setDbHandler( $oMod->getDbHandler_IPs() )
|
80 |
-
->setIP( $sIp )
|
81 |
-
->fromBlacklist();
|
82 |
-
Services::Response()->redirectToHome();
|
83 |
-
}
|
84 |
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
|
88 |
private function renderKillPage() {
|
89 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
90 |
-
$
|
91 |
-
/** @var IPs\Options $
|
92 |
-
$
|
93 |
-
$
|
94 |
-
$oLoginMod = $
|
95 |
|
96 |
$sUniqId = 'uau'.uniqid();
|
97 |
|
98 |
-
$
|
99 |
-
$nTimeRemaining = max( floor( $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
$aData = [
|
101 |
'strings' => [
|
102 |
'title' => sprintf( __( "You've been blocked by the %s plugin", 'wp-simple-firewall' ),
|
103 |
sprintf( '<a href="%s" target="_blank">%s</a>',
|
104 |
-
$
|
105 |
-
$
|
106 |
)
|
107 |
),
|
108 |
'lines' => [
|
109 |
sprintf( __( 'Time remaining on black list: %s', 'wp-simple-firewall' ),
|
110 |
sprintf( _n( '%s minute', '%s minutes', $nTimeRemaining, 'wp-simple-firewall' ), $nTimeRemaining )
|
111 |
),
|
112 |
-
sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $
|
113 |
sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
|
114 |
],
|
115 |
'your_ip' => 'Your IP address',
|
@@ -119,10 +87,13 @@ class BlockRequest {
|
|
119 |
'button' => __( 'Unblock My IP Address', 'wp-simple-firewall' ),
|
120 |
],
|
121 |
],
|
|
|
|
|
|
|
122 |
'vars' => [
|
123 |
-
'nonce' => $
|
124 |
-
'ip' => $
|
125 |
-
'gasp_element' => $
|
126 |
'snippets/gasp_js.php',
|
127 |
[
|
128 |
'sCbName' => $oLoginMod->getGaspKey(),
|
@@ -138,13 +109,68 @@ class BlockRequest {
|
|
138 |
),
|
139 |
],
|
140 |
'flags' => [
|
141 |
-
'is_autorecover'
|
142 |
-
'
|
|
|
143 |
],
|
144 |
];
|
145 |
Services::WpGeneral()
|
146 |
->wpDie(
|
147 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
);
|
|
|
|
|
|
|
|
|
149 |
}
|
150 |
}
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
use FernleafSystems\Wordpress\Services\Utilities\Obfuscate;
|
9 |
|
10 |
class BlockRequest {
|
11 |
|
12 |
use ModConsumer;
|
13 |
|
14 |
public function run() {
|
15 |
+
if ( $this->isBlocked() ) {
|
|
|
16 |
|
17 |
+
if ( $this->isAutoUnBlocked() ) {
|
18 |
+
// TODO: flash message
|
19 |
+
Services::Response()->redirectToAdmin();
|
20 |
+
}
|
21 |
|
|
|
22 |
// don't log killed requests
|
23 |
add_filter( $this->getCon()->prefix( 'is_log_traffic' ), '__return_false' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
$this->getCon()->fireEvent( 'conn_kill' );
|
25 |
$this->renderKillPage();
|
26 |
}
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
+
* @return bool
|
31 |
*/
|
32 |
+
private function isBlocked() {
|
33 |
+
return ( new IPs\Components\QueryIpBlock() )
|
34 |
+
->setMod( $this->getMod() )
|
35 |
+
->setIp( Services::IP()->getRequestIp() )
|
36 |
+
->run();
|
37 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
+
/**
|
40 |
+
* @return bool
|
41 |
+
*/
|
42 |
+
private function isAutoUnBlocked() {
|
43 |
+
return ( new AutoUnblock() )
|
44 |
+
->setMod( $this->getMod() )
|
45 |
+
->run();
|
46 |
}
|
47 |
|
48 |
private function renderKillPage() {
|
49 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
50 |
+
$mod = $this->getMod();
|
51 |
+
/** @var IPs\Options $opts */
|
52 |
+
$opts = $this->getOptions();
|
53 |
+
$con = $this->getCon();
|
54 |
+
$oLoginMod = $con->getModule_LoginGuard();
|
55 |
|
56 |
$sUniqId = 'uau'.uniqid();
|
57 |
|
58 |
+
$sIP = Services::IP()->getRequestIp();
|
59 |
+
$nTimeRemaining = max( floor( $opts->getAutoExpireTime()/60 ), 0 );
|
60 |
+
|
61 |
+
$user = Services::WpUsers()->getCurrentWpUser();
|
62 |
+
$bCanUauGasp = $opts->isEnabledAutoVisitorRecover() && $opts->getCanIpRequestAutoUnblock( $sIP );
|
63 |
+
$bCanUauMagic = $opts->isEnabledMagicEmailLinkRecover() &&
|
64 |
+
$user instanceof \WP_User
|
65 |
+
&& $opts->getCanRequestAutoUnblockEmailLink( $user );
|
66 |
+
$bCanAutoRecover = $bCanUauGasp || $bCanUauMagic;
|
67 |
+
|
68 |
$aData = [
|
69 |
'strings' => [
|
70 |
'title' => sprintf( __( "You've been blocked by the %s plugin", 'wp-simple-firewall' ),
|
71 |
sprintf( '<a href="%s" target="_blank">%s</a>',
|
72 |
+
$con->getPluginSpec()[ 'meta' ][ 'url_repo_home' ],
|
73 |
+
$con->getHumanName()
|
74 |
)
|
75 |
),
|
76 |
'lines' => [
|
77 |
sprintf( __( 'Time remaining on black list: %s', 'wp-simple-firewall' ),
|
78 |
sprintf( _n( '%s minute', '%s minutes', $nTimeRemaining, 'wp-simple-firewall' ), $nTimeRemaining )
|
79 |
),
|
80 |
+
sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $opts->getOffenseLimit() ),
|
81 |
sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
|
82 |
],
|
83 |
'your_ip' => 'Your IP address',
|
87 |
'button' => __( 'Unblock My IP Address', 'wp-simple-firewall' ),
|
88 |
],
|
89 |
],
|
90 |
+
'content' => [
|
91 |
+
'email_unblock' => $this->renderEmailMagicLinkContent()
|
92 |
+
],
|
93 |
'vars' => [
|
94 |
+
'nonce' => $mod->getNonceActionData( 'uau' ),
|
95 |
+
'ip' => $sIP,
|
96 |
+
'gasp_element' => $mod->renderTemplate(
|
97 |
'snippets/gasp_js.php',
|
98 |
[
|
99 |
'sCbName' => $oLoginMod->getGaspKey(),
|
109 |
),
|
110 |
],
|
111 |
'flags' => [
|
112 |
+
'is_autorecover' => $bCanAutoRecover,
|
113 |
+
'is_uaug_permitted' => $bCanUauGasp,
|
114 |
+
'is_uaum_permitted' => $bCanUauMagic,
|
115 |
],
|
116 |
];
|
117 |
Services::WpGeneral()
|
118 |
->wpDie(
|
119 |
+
$mod->renderTemplate( '/pages/block/blocklist_die.twig', $aData, true )
|
120 |
+
);
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @return string
|
125 |
+
*/
|
126 |
+
private function renderEmailMagicLinkContent() {
|
127 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
128 |
+
$mod = $this->getMod();
|
129 |
+
/** @var IPs\Options $opts */
|
130 |
+
$opts = $this->getOptions();
|
131 |
+
$con = $this->getCon();
|
132 |
+
|
133 |
+
$content = '';
|
134 |
+
|
135 |
+
$user = Services::WpUsers()->getCurrentWpUser();
|
136 |
+
if ( $user instanceof \WP_User &&
|
137 |
+
$opts->isEnabledMagicEmailLinkRecover()
|
138 |
+
&& $opts->getCanRequestAutoUnblockEmailLink( $user ) ) {
|
139 |
+
|
140 |
+
if ( apply_filters( $con->prefix( 'can_user_magic_link' ), true ) ) {
|
141 |
+
$content = $mod->renderTemplate(
|
142 |
+
'/pages/block/magic_link.twig',
|
143 |
+
[
|
144 |
+
'flags' => [
|
145 |
+
],
|
146 |
+
'hrefs' => [
|
147 |
+
'unblock' => add_query_arg(
|
148 |
+
array_merge(
|
149 |
+
$mod->getNonceActionData( 'uaum-init-'.substr( sha1( $user->user_login ), 0, 6 ) ),
|
150 |
+
[
|
151 |
+
'ip' => Services::IP()->getRequestIp()
|
152 |
+
]
|
153 |
+
),
|
154 |
+
Services::WpGeneral()->getHomeUrl()
|
155 |
+
)
|
156 |
+
],
|
157 |
+
'vars' => [
|
158 |
+
'email' => Obfuscate::Email( $user->user_email )
|
159 |
+
],
|
160 |
+
'strings' => [
|
161 |
+
'you_may' => __( 'You can automatically unblock your IP address by clicking the link below.', 'wp-simple-firewall' ),
|
162 |
+
'this_will_send' => __( 'Clicking the button will send you an email letting you unblock your IP address.', 'wp-simple-firewall' ),
|
163 |
+
'assumes_email' => __( 'This assumes that your WordPress site has been properly configured to send email - many are not.', 'wp-simple-firewall' ),
|
164 |
+
'dont_receive' => __( "If you don't receive the email, check your spam and contact your site admin.", 'wp-simple-firewall' ),
|
165 |
+
'limit_60' => __( "You may only use this link once every 60 minutes. If you're repeatedly blocked, ask your site admin to review the audit trail to determine the cause.", 'wp-simple-firewall' ),
|
166 |
+
'same_browser' => __( "When you click the link from your email, it must open up in this web browser.", 'wp-simple-firewall' ),
|
167 |
+
'click_to_send' => __( 'Send Auto-Unblock Link To My Email', 'wp-simple-firewall' )
|
168 |
+
],
|
169 |
+
]
|
170 |
);
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
return $content;
|
175 |
}
|
176 |
}
|
src/lib/src/Modules/IPs/Lib/Ops/DeleteIp.php
CHANGED
@@ -15,11 +15,6 @@ class DeleteIp {
|
|
15 |
use Databases\Base\HandlerConsumer;
|
16 |
use IPs\Components\IpAddressConsumer;
|
17 |
|
18 |
-
/**
|
19 |
-
* @var string
|
20 |
-
*/
|
21 |
-
private $sIpAddress;
|
22 |
-
|
23 |
/**
|
24 |
* @return bool
|
25 |
*/
|
@@ -47,20 +42,4 @@ class DeleteIp {
|
|
47 |
return $oDel->filterByIp( $this->getIP() )
|
48 |
->setLimit( 1 );
|
49 |
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @return string
|
53 |
-
*/
|
54 |
-
public function getIP() {
|
55 |
-
return $this->sIpAddress;
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* @param string $sIP
|
60 |
-
* @return $this
|
61 |
-
*/
|
62 |
-
public function setIP( $sIP ) {
|
63 |
-
$this->sIpAddress = $sIP;
|
64 |
-
return $this;
|
65 |
-
}
|
66 |
}
|
15 |
use Databases\Base\HandlerConsumer;
|
16 |
use IPs\Components\IpAddressConsumer;
|
17 |
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* @return bool
|
20 |
*/
|
42 |
return $oDel->filterByIp( $this->getIP() )
|
43 |
->setLimit( 1 );
|
44 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
src/lib/src/Modules/IPs/Lib/{BlackmarkRequest.php → ProcessOffenses.php}
RENAMED
@@ -6,32 +6,33 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
-
class
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
13 |
public function run() {
|
14 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
15 |
-
$
|
16 |
|
17 |
-
$
|
18 |
|
19 |
-
$
|
20 |
-
add_filter( $
|
21 |
-
add_action( $
|
22 |
$this->processOffense();
|
23 |
} );
|
24 |
add_action( 'shield_security_offense', [ $this, 'processCustomShieldOffense' ], 10, 3 );
|
25 |
}
|
26 |
|
27 |
private function processOffense() {
|
28 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $
|
29 |
-
$
|
30 |
|
31 |
-
$oTracker = $
|
32 |
-
if ( !$this->getCon()->plugin_deleting
|
|
|
33 |
( new IPs\Components\ProcessOffense() )
|
34 |
-
->setMod( $
|
35 |
->setIp( Services::IP()->getRequestIp() )
|
36 |
->run();
|
37 |
}
|
@@ -48,10 +49,10 @@ class BlackmarkRequest {
|
|
48 |
|
49 |
$aMessages[] = sprintf( '<p>%s</p>', sprintf(
|
50 |
$this->getMod()->getTextOpt( 'text_remainingtrans' ),
|
51 |
-
( new IPs\Components\QueryRemainingOffenses() )
|
52 |
->setMod( $this->getMod() )
|
53 |
->setIP( Services::IP()->getRequestIp() )
|
54 |
-
->run()
|
55 |
) );
|
56 |
|
57 |
return $aMessages;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
+
class ProcessOffenses {
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
13 |
public function run() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
15 |
+
$mod = $this->getMod();
|
16 |
|
17 |
+
$mod->loadOffenseTracker()->setIfCommit( true );
|
18 |
|
19 |
+
$con = $this->getCon();
|
20 |
+
add_filter( $con->prefix( 'firewall_die_message' ), [ $this, 'augmentFirewallDieMessage' ] );
|
21 |
+
add_action( $con->prefix( 'pre_plugin_shutdown' ), function () {
|
22 |
$this->processOffense();
|
23 |
} );
|
24 |
add_action( 'shield_security_offense', [ $this, 'processCustomShieldOffense' ], 10, 3 );
|
25 |
}
|
26 |
|
27 |
private function processOffense() {
|
28 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $mod */
|
29 |
+
$mod = $this->getMod();
|
30 |
|
31 |
+
$oTracker = $mod->loadOffenseTracker();
|
32 |
+
if ( !$this->getCon()->plugin_deleting
|
33 |
+
&& $oTracker->hasVisitorOffended() && $oTracker->isCommit() ) {
|
34 |
( new IPs\Components\ProcessOffense() )
|
35 |
+
->setMod( $mod )
|
36 |
->setIp( Services::IP()->getRequestIp() )
|
37 |
->run();
|
38 |
}
|
49 |
|
50 |
$aMessages[] = sprintf( '<p>%s</p>', sprintf(
|
51 |
$this->getMod()->getTextOpt( 'text_remainingtrans' ),
|
52 |
+
max( 0, ( new IPs\Components\QueryRemainingOffenses() )
|
53 |
->setMod( $this->getMod() )
|
54 |
->setIP( Services::IP()->getRequestIp() )
|
55 |
+
->run() )
|
56 |
) );
|
57 |
|
58 |
return $aMessages;
|
src/lib/src/Modules/IPs/Options.php
CHANGED
@@ -23,13 +23,31 @@ class Options extends Base\ShieldOptions {
|
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
* @return bool
|
28 |
*/
|
29 |
-
public function
|
30 |
-
$
|
31 |
-
return !array_key_exists( $
|
32 |
-
|| ( Services::Request()->carbon()->
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -41,6 +59,7 @@ class Options extends Base\ShieldOptions {
|
|
41 |
|
42 |
/**
|
43 |
* @return string[]
|
|
|
44 |
*/
|
45 |
public function getDbColumns_IPs() {
|
46 |
return $this->getDef( 'ip_list_table_columns' );
|
@@ -75,8 +94,15 @@ class Options extends Base\ShieldOptions {
|
|
75 |
/**
|
76 |
* @return bool
|
77 |
*/
|
78 |
-
public function
|
79 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
}
|
81 |
|
82 |
/**
|
@@ -122,34 +148,34 @@ class Options extends Base\ShieldOptions {
|
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
-
* @param string $
|
126 |
* @return bool
|
127 |
*/
|
128 |
-
public function isTrackOptTransgression( $
|
129 |
-
return strpos( $this->getOpt( $
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
-
* @param string $
|
134 |
* @return bool
|
135 |
*/
|
136 |
-
public function isTrackOptDoubleTransgression( $
|
137 |
-
return $this->isOpt( $
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
-
* @param string $
|
142 |
* @return bool
|
143 |
*/
|
144 |
-
public function isTrackOptImmediateBlock( $
|
145 |
-
return $this->isOpt( $
|
146 |
}
|
147 |
|
148 |
/**
|
149 |
-
* @param string $
|
150 |
* @return bool
|
151 |
*/
|
152 |
-
protected function isSelectOptionEnabled( $
|
153 |
-
return !$this->isOpt( $
|
154 |
}
|
155 |
}
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
+
* @return array
|
27 |
+
*/
|
28 |
+
public function getAutoUnblockEmailIDs() {
|
29 |
+
$aIps = $this->getOpt( 'autounblock_emailids', [] );
|
30 |
+
return is_array( $aIps ) ? $aIps : [];
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param string $ip
|
35 |
+
* @return bool
|
36 |
+
*/
|
37 |
+
public function getCanIpRequestAutoUnblock( $ip ) {
|
38 |
+
$existing = $this->getAutoUnblockIps();
|
39 |
+
return !array_key_exists( $ip, $existing )
|
40 |
+
|| ( Services::Request()->carbon()->subDay( 1 )->timestamp > $existing[ $ip ] );
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param \WP_User $user
|
45 |
* @return bool
|
46 |
*/
|
47 |
+
public function getCanRequestAutoUnblockEmailLink( \WP_User $user ) {
|
48 |
+
$existing = $this->getAutoUnblockEmailIDs();
|
49 |
+
return !array_key_exists( $user->ID, $existing )
|
50 |
+
|| ( Services::Request()->carbon()->subHour( 1 )->timestamp > $existing[ $user->ID ] );
|
51 |
}
|
52 |
|
53 |
/**
|
59 |
|
60 |
/**
|
61 |
* @return string[]
|
62 |
+
* @deprecated 9.2.0
|
63 |
*/
|
64 |
public function getDbColumns_IPs() {
|
65 |
return $this->getDef( 'ip_list_table_columns' );
|
94 |
/**
|
95 |
* @return bool
|
96 |
*/
|
97 |
+
public function isEnabledAutoVisitorRecover() {
|
98 |
+
return in_array( 'gasp', (array)$this->getOpt( 'user_auto_recover', [] ) );
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @return bool
|
103 |
+
*/
|
104 |
+
public function isEnabledMagicEmailLinkRecover() {
|
105 |
+
return in_array( 'email', (array)$this->getOpt( 'user_auto_recover', [] ) );
|
106 |
}
|
107 |
|
108 |
/**
|
148 |
}
|
149 |
|
150 |
/**
|
151 |
+
* @param string $key
|
152 |
* @return bool
|
153 |
*/
|
154 |
+
public function isTrackOptTransgression( $key ) {
|
155 |
+
return strpos( $this->getOpt( $key ), 'transgression' ) !== false;
|
156 |
}
|
157 |
|
158 |
/**
|
159 |
+
* @param string $key
|
160 |
* @return bool
|
161 |
*/
|
162 |
+
public function isTrackOptDoubleTransgression( $key ) {
|
163 |
+
return $this->isOpt( $key, 'transgression-double' );
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
+
* @param string $key
|
168 |
* @return bool
|
169 |
*/
|
170 |
+
public function isTrackOptImmediateBlock( $key ) {
|
171 |
+
return $this->isOpt( $key, 'block' );
|
172 |
}
|
173 |
|
174 |
/**
|
175 |
+
* @param string $key
|
176 |
* @return bool
|
177 |
*/
|
178 |
+
protected function isSelectOptionEnabled( $key ) {
|
179 |
+
return !$this->isOpt( $key, 'disabled' );
|
180 |
}
|
181 |
}
|
src/lib/src/Modules/IPs/Strings.php
CHANGED
@@ -8,17 +8,17 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
class Strings extends Base\Strings {
|
9 |
|
10 |
/**
|
11 |
-
* @param string $
|
12 |
* @return array
|
13 |
* @throws \Exception
|
14 |
*/
|
15 |
-
public function getSectionStrings( $
|
16 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
17 |
$oMod = $this->getMod();
|
18 |
$sPlugName = $this->getCon()->getHumanName();
|
19 |
$sModName = $oMod->getMainFeatureName();
|
20 |
|
21 |
-
switch ( $
|
22 |
|
23 |
case 'section_enable_plugin_feature_ips' :
|
24 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -39,7 +39,7 @@ class Strings extends Base\Strings {
|
|
39 |
__( "Think of 'offenses' as just a counter for the number of times a visitor does something bad.", 'wp-simple-firewall' )
|
40 |
.' '.sprintf(
|
41 |
__( 'When the counter reaches the limit below (default: %s), %s will block that IP completely.', 'wp-simple-firewall' ),
|
42 |
-
$
|
43 |
$sPlugName
|
44 |
)
|
45 |
];
|
@@ -91,7 +91,7 @@ class Strings extends Base\Strings {
|
|
91 |
break;
|
92 |
|
93 |
default:
|
94 |
-
return parent::getSectionStrings( $
|
95 |
}
|
96 |
|
97 |
return [
|
@@ -102,16 +102,16 @@ class Strings extends Base\Strings {
|
|
102 |
}
|
103 |
|
104 |
/**
|
105 |
-
* @param string $
|
106 |
* @return array
|
107 |
* @throws \Exception
|
108 |
*/
|
109 |
-
public function getOptionStrings( $
|
110 |
|
111 |
$sPlugName = $this->getCon()->getHumanName();
|
112 |
$sModName = $this->getMod()->getMainFeatureName();
|
113 |
|
114 |
-
switch ( $
|
115 |
|
116 |
case 'enable_ips' :
|
117 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -122,17 +122,22 @@ class Strings extends Base\Strings {
|
|
122 |
case 'transgression_limit' :
|
123 |
$sName = __( 'Offense Limit', 'wp-simple-firewall' );
|
124 |
$sSummary = __( 'Visitor IP address will be Black Listed after X bad actions on your site', 'wp-simple-firewall' );
|
125 |
-
$sDescription =
|
126 |
-
|
127 |
-
|
|
|
|
|
128 |
break;
|
129 |
|
130 |
case 'auto_expire' :
|
131 |
$sName = __( 'Auto Block Expiration', 'wp-simple-firewall' );
|
132 |
$sSummary = __( 'After 1 "X" a black listed IP will be removed from the black list', 'wp-simple-firewall' );
|
133 |
-
$sDescription =
|
134 |
-
|
135 |
-
|
|
|
|
|
|
|
136 |
break;
|
137 |
|
138 |
case 'user_auto_recover' :
|
@@ -203,19 +208,26 @@ class Strings extends Base\Strings {
|
|
203 |
case 'track_fakewebcrawler' :
|
204 |
$sName = __( 'Fake Web Crawler', 'wp-simple-firewall' );
|
205 |
$sSummary = __( 'Detect Fake Search Engine Crawlers', 'wp-simple-firewall' );
|
206 |
-
$sDescription =
|
|
|
|
|
|
|
|
|
207 |
break;
|
208 |
|
209 |
case 'track_useragent' :
|
210 |
$sName = __( 'Empty User Agents', 'wp-simple-firewall' );
|
211 |
$sSummary = __( 'Detect Requests With Empty User Agents', 'wp-simple-firewall' );
|
212 |
-
$sDescription =
|
213 |
-
|
214 |
-
|
|
|
|
|
|
|
215 |
break;
|
216 |
|
217 |
default:
|
218 |
-
return parent::getOptionStrings( $
|
219 |
}
|
220 |
|
221 |
return [
|
8 |
class Strings extends Base\Strings {
|
9 |
|
10 |
/**
|
11 |
+
* @param string $section
|
12 |
* @return array
|
13 |
* @throws \Exception
|
14 |
*/
|
15 |
+
public function getSectionStrings( $section ) {
|
16 |
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
17 |
$oMod = $this->getMod();
|
18 |
$sPlugName = $this->getCon()->getHumanName();
|
19 |
$sModName = $oMod->getMainFeatureName();
|
20 |
|
21 |
+
switch ( $section ) {
|
22 |
|
23 |
case 'section_enable_plugin_feature_ips' :
|
24 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
39 |
__( "Think of 'offenses' as just a counter for the number of times a visitor does something bad.", 'wp-simple-firewall' )
|
40 |
.' '.sprintf(
|
41 |
__( 'When the counter reaches the limit below (default: %s), %s will block that IP completely.', 'wp-simple-firewall' ),
|
42 |
+
$this->getOptions()->getOptDefault( 'transgression_limit' ),
|
43 |
$sPlugName
|
44 |
)
|
45 |
];
|
91 |
break;
|
92 |
|
93 |
default:
|
94 |
+
return parent::getSectionStrings( $section );
|
95 |
}
|
96 |
|
97 |
return [
|
102 |
}
|
103 |
|
104 |
/**
|
105 |
+
* @param string $key
|
106 |
* @return array
|
107 |
* @throws \Exception
|
108 |
*/
|
109 |
+
public function getOptionStrings( $key ) {
|
110 |
|
111 |
$sPlugName = $this->getCon()->getHumanName();
|
112 |
$sModName = $this->getMod()->getMainFeatureName();
|
113 |
|
114 |
+
switch ( $key ) {
|
115 |
|
116 |
case 'enable_ips' :
|
117 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
122 |
case 'transgression_limit' :
|
123 |
$sName = __( 'Offense Limit', 'wp-simple-firewall' );
|
124 |
$sSummary = __( 'Visitor IP address will be Black Listed after X bad actions on your site', 'wp-simple-firewall' );
|
125 |
+
$sDescription = [
|
126 |
+
sprintf( __( 'An offense is registered against an IP address each time a visitor trips the defenses of the %s plugin.', 'wp-simple-firewall' ), $sPlugName ),
|
127 |
+
__( 'When the number of these offenses exceeds the limit, they are automatically blocked from accessing the site.', 'wp-simple-firewall' ),
|
128 |
+
sprintf( __( 'Set this to "0" to turn off the %s feature.', 'wp-simple-firewall' ), __( 'Automatic IP Black List', 'wp-simple-firewall' ) )
|
129 |
+
];
|
130 |
break;
|
131 |
|
132 |
case 'auto_expire' :
|
133 |
$sName = __( 'Auto Block Expiration', 'wp-simple-firewall' );
|
134 |
$sSummary = __( 'After 1 "X" a black listed IP will be removed from the black list', 'wp-simple-firewall' );
|
135 |
+
$sDescription = [
|
136 |
+
__( 'Blocked IP addresses are eventually removed.', 'wp-simple-firewall' )
|
137 |
+
.'<br/>'.__( 'This option lets you specify how long they should be kept.', 'wp-simple-firewall' ),
|
138 |
+
__( 'Large, permanent IP Block Lists will degrade site performance.', 'wp-simple-firewall' ),
|
139 |
+
__( 'Shorter IP black lists are more efficient and a more intelligent use of an IP-based blocking system.', 'wp-simple-firewall' )
|
140 |
+
];
|
141 |
break;
|
142 |
|
143 |
case 'user_auto_recover' :
|
208 |
case 'track_fakewebcrawler' :
|
209 |
$sName = __( 'Fake Web Crawler', 'wp-simple-firewall' );
|
210 |
$sSummary = __( 'Detect Fake Search Engine Crawlers', 'wp-simple-firewall' );
|
211 |
+
$sDescription = [
|
212 |
+
__( "Identify a visitor as a Bot when it presents as an official web crawler, but analysis shows it's fake.", 'wp-simple-firewall' ),
|
213 |
+
__( "Many bots pretend to be a Google Bot.", 'wp-simple-firewall' )
|
214 |
+
.'<br/>'.__( "We can then know that a bot isn't here for anything good and block them.", 'wp-simple-firewall' ),
|
215 |
+
];
|
216 |
break;
|
217 |
|
218 |
case 'track_useragent' :
|
219 |
$sName = __( 'Empty User Agents', 'wp-simple-firewall' );
|
220 |
$sSummary = __( 'Detect Requests With Empty User Agents', 'wp-simple-firewall' );
|
221 |
+
$sDescription = [
|
222 |
+
__( "Identify a bot when the user agent is not provided.", 'wp-simple-firewall' ),
|
223 |
+
sprintf( '%s:<br/><code>%s</code>',
|
224 |
+
__( 'For example, your browser user agent is', 'wp-simple-firewall' ), Services::Request()
|
225 |
+
->getUserAgent() )
|
226 |
+
];
|
227 |
break;
|
228 |
|
229 |
default:
|
230 |
+
return parent::getOptionStrings( $key );
|
231 |
}
|
232 |
|
233 |
return [
|
src/lib/src/Modules/IPs/UI.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class UI extends Base\ShieldUI {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param string $section
|
12 |
+
* @return array
|
13 |
+
*/
|
14 |
+
protected function getSectionWarnings( $section ) {
|
15 |
+
$aWarnings = [];
|
16 |
+
|
17 |
+
/** @var Options $opts */
|
18 |
+
$opts = $this->getOptions();
|
19 |
+
|
20 |
+
switch ( $section ) {
|
21 |
+
|
22 |
+
case 'section_auto_black_list':
|
23 |
+
if ( !$opts->isEnabledAutoBlackList() ) {
|
24 |
+
$aWarnings[] = sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ), __( "IP blocking is turned-off because the offenses limit is set to 0.", 'wp-simple-firewall' ) );
|
25 |
+
}
|
26 |
+
break;
|
27 |
+
|
28 |
+
case 'section_behaviours':
|
29 |
+
case 'section_probes':
|
30 |
+
case 'section_logins':
|
31 |
+
if ( !$opts->isEnabledAutoBlackList() ) {
|
32 |
+
$aWarnings[] = __( "Since the offenses limit is set to 0, these options have no effect.", 'wp-simple-firewall' );
|
33 |
+
}
|
34 |
+
|
35 |
+
if ( $section == 'section_behaviours' && strlen( Services::Request()->getUserAgent() ) == 0 ) {
|
36 |
+
$aWarnings[] = __( "Your User Agent appears to be empty. We recommend not turning on this option.", 'wp-simple-firewall' );
|
37 |
+
}
|
38 |
+
break;
|
39 |
+
}
|
40 |
+
|
41 |
+
return $aWarnings;
|
42 |
+
}
|
43 |
+
}
|
src/lib/src/Modules/IPs/Upgrade.php
CHANGED
@@ -16,4 +16,30 @@ class Upgrade extends Base\Upgrade {
|
|
16 |
$oDBH->getTable(), 'ip', $oDBH->enumerateColumns()[ 'ip' ] )
|
17 |
);
|
18 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
16 |
$oDBH->getTable(), 'ip', $oDBH->enumerateColumns()[ 'ip' ] )
|
17 |
);
|
18 |
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Support larger transgression counts [smallint(1) => int(10)]
|
22 |
+
*/
|
23 |
+
protected function upgrade_911() {
|
24 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
25 |
+
$oMod = $this->getMod();
|
26 |
+
$oDBH = $oMod->getDbHandler_IPs();
|
27 |
+
Services::WpDb()->doSql(
|
28 |
+
sprintf( "ALTER TABLE `%s` MODIFY `%s` %s;",
|
29 |
+
$oDBH->getTable(), 'transgressions', $oDBH->enumerateColumns()[ 'transgressions' ] )
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Support Magic Links for logged-in users.
|
35 |
+
*/
|
36 |
+
protected function upgrade_920() {
|
37 |
+
/** @var Options $oOpts */
|
38 |
+
$oOpts = $this->getOptions();
|
39 |
+
$current = $oOpts->getOpt( 'user_auto_recover' );
|
40 |
+
if ( !is_array( $current ) ) {
|
41 |
+
$current = ( $current === 'gasp' ) ? [ 'gasp' ] : [];
|
42 |
+
$oOpts->setOpt( 'user_auto_recover', $current );
|
43 |
+
}
|
44 |
+
}
|
45 |
}
|
src/lib/src/Modules/License/AjaxHandler.php
CHANGED
@@ -9,12 +9,12 @@ use FernleafSystems\Wordpress\Services\Utilities\Licenses\Keyless;
|
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
11 |
/**
|
12 |
-
* @param string $
|
13 |
* @return array
|
14 |
*/
|
15 |
-
protected function processAjaxAction( $
|
16 |
|
17 |
-
switch ( $
|
18 |
case 'license_handling':
|
19 |
$aResponse = $this->ajaxExec_LicenseHandling();
|
20 |
break;
|
@@ -23,7 +23,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
23 |
break;
|
24 |
|
25 |
default:
|
26 |
-
$aResponse = parent::processAjaxAction( $
|
27 |
}
|
28 |
|
29 |
return $aResponse;
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
11 |
/**
|
12 |
+
* @param string $action
|
13 |
* @return array
|
14 |
*/
|
15 |
+
protected function processAjaxAction( $action ) {
|
16 |
|
17 |
+
switch ( $action ) {
|
18 |
case 'license_handling':
|
19 |
$aResponse = $this->ajaxExec_LicenseHandling();
|
20 |
break;
|
23 |
break;
|
24 |
|
25 |
default:
|
26 |
+
$aResponse = parent::processAjaxAction( $action );
|
27 |
}
|
28 |
|
29 |
return $aResponse;
|
src/lib/src/Modules/License/Lib/WpHashes/ApiTokenManager.php
CHANGED
@@ -64,14 +64,6 @@ class ApiTokenManager {
|
|
64 |
return empty( $aT[ 'token' ] ) ? '' : $aT[ 'token' ];
|
65 |
}
|
66 |
|
67 |
-
/**
|
68 |
-
* @return string
|
69 |
-
* @deprecated 9.0.3
|
70 |
-
*/
|
71 |
-
private function getTheToken() {
|
72 |
-
return $this->loadToken()[ 'token' ];
|
73 |
-
}
|
74 |
-
|
75 |
/**
|
76 |
* @return bool
|
77 |
*/
|
64 |
return empty( $aT[ 'token' ] ) ? '' : $aT[ 'token' ];
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
/**
|
68 |
* @return bool
|
69 |
*/
|
src/lib/src/Modules/License/UI.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class UI extends Base\ShieldUI {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
public function buildInsightsVars() {
|
14 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $mod */
|
15 |
+
$mod = $this->getMod();
|
16 |
+
$con = $this->getCon();
|
17 |
+
$opts = $this->getOptions();
|
18 |
+
$oWp = Services::WpGeneral();
|
19 |
+
$oCarbon = Services::Request()->carbon();
|
20 |
+
|
21 |
+
$oCurrent = $mod->getLicenseHandler()->getLicense();
|
22 |
+
|
23 |
+
$nExpiresAt = $oCurrent->getExpiresAt();
|
24 |
+
if ( $nExpiresAt > 0 && $nExpiresAt != PHP_INT_MAX ) {
|
25 |
+
$sExpiresAt = $oCarbon->setTimestamp( $nExpiresAt )->diffForHumans()
|
26 |
+
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nExpiresAt ) );
|
27 |
+
}
|
28 |
+
else {
|
29 |
+
$sExpiresAt = 'n/a';
|
30 |
+
}
|
31 |
+
|
32 |
+
$nLastReqAt = $oCurrent->last_request_at;
|
33 |
+
if ( empty( $nLastReqAt ) ) {
|
34 |
+
$sChecked = __( 'Never', 'wp-simple-firewall' );
|
35 |
+
}
|
36 |
+
else {
|
37 |
+
$sChecked = $oCarbon->setTimestamp( $nLastReqAt )->diffForHumans()
|
38 |
+
.sprintf( '<br/><small>%s</small>', $oWp->getTimeStampForDisplay( $nLastReqAt ) );
|
39 |
+
}
|
40 |
+
$aLicenseTableVars = [
|
41 |
+
'product_name' => $oCurrent->is_central ?
|
42 |
+
$opts->getDef( 'license_item_name_sc' ) :
|
43 |
+
$opts->getDef( 'license_item_name' ),
|
44 |
+
'license_active' => $mod->getLicenseHandler()->hasValidWorkingLicense() ?
|
45 |
+
__( '✔', 'wp-simple-firewall' ) : __( '✖', 'wp-simple-firewall' ),
|
46 |
+
'license_expires' => $sExpiresAt,
|
47 |
+
'license_email' => $oCurrent->customer_email,
|
48 |
+
'last_checked' => $sChecked,
|
49 |
+
'last_errors' => $mod->hasLastErrors() ? $mod->getLastErrors( true ) : '',
|
50 |
+
'wphashes_token' => $mod->getWpHashesTokenManager()->hasToken() ?
|
51 |
+
__( '✔', 'wp-simple-firewall' ) : __( '✖', 'wp-simple-firewall' ),
|
52 |
+
'installation_id' => $con->getSiteInstallationId(),
|
53 |
+
];
|
54 |
+
return [
|
55 |
+
'vars' => [
|
56 |
+
'license_table' => $aLicenseTableVars,
|
57 |
+
'activation_url' => $oWp->getHomeUrl(),
|
58 |
+
'error' => $mod->getLastErrors( true )
|
59 |
+
],
|
60 |
+
'inputs' => [
|
61 |
+
'license_key' => [
|
62 |
+
'name' => $con->prefixOption( 'license_key' ),
|
63 |
+
'maxlength' => $opts->getDef( 'license_key_length' ),
|
64 |
+
]
|
65 |
+
],
|
66 |
+
'ajax' => [
|
67 |
+
'license_handling' => $mod->getAjaxActionData( 'license_handling' ),
|
68 |
+
'connection_debug' => $mod->getAjaxActionData( 'connection_debug' )
|
69 |
+
],
|
70 |
+
'aHrefs' => [
|
71 |
+
'shield_pro_url' => 'https://shsec.io/shieldpro',
|
72 |
+
'shield_pro_more_info_url' => 'https://shsec.io/shld1',
|
73 |
+
'iframe_url' => $opts->getDef( 'landing_page_url' ),
|
74 |
+
'keyless_cp' => $opts->getDef( 'keyless_cp' ),
|
75 |
+
],
|
76 |
+
'flags' => [
|
77 |
+
'show_ads' => false,
|
78 |
+
'button_enabled_check' => true,
|
79 |
+
'show_standard_options' => false,
|
80 |
+
'show_alt_content' => true,
|
81 |
+
'is_pro' => $con->isPremiumActive(),
|
82 |
+
'has_error' => $mod->hasLastErrors()
|
83 |
+
],
|
84 |
+
'strings' => $mod->getStrings()->getDisplayStrings(),
|
85 |
+
];
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return bool
|
90 |
+
*/
|
91 |
+
public function isEnabledForUiSummary() {
|
92 |
+
/** @var \ICWP_WPSF_FeatureHandler_License $mod */
|
93 |
+
$mod = $this->getMod();
|
94 |
+
return $mod->getLicenseHandler()->hasValidWorkingLicense();
|
95 |
+
}
|
96 |
+
}
|
src/lib/src/Modules/Lockdown/Lib/CleanRubbish.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Lockdown\Lib;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\OneTimeExecute;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class CleanRubbish {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
use OneTimeExecute;
|
13 |
+
|
14 |
+
protected function run() {
|
15 |
+
if ( Services::WpGeneral()->isCron() && $this->getOptions()->isOpt( 'clean_wp_rubbish', 'Y' ) ) {
|
16 |
+
add_action( $this->getCon()->prefix( 'daily_cron' ), function () {
|
17 |
+
$FS = Services::WpFs();
|
18 |
+
$allFiles = $FS->getAllFilesInDir( ABSPATH, false );
|
19 |
+
foreach ( $allFiles as $file ) {
|
20 |
+
if ( in_array( basename( $file ), $this->getFilesToClean() ) ) {
|
21 |
+
$FS->deleteFile( $file );
|
22 |
+
}
|
23 |
+
}
|
24 |
+
} );
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return string[]
|
30 |
+
*/
|
31 |
+
private function getFilesToClean() {
|
32 |
+
return [
|
33 |
+
'wp-config-sample.php',
|
34 |
+
'readme.html',
|
35 |
+
'license.txt',
|
36 |
+
];
|
37 |
+
}
|
38 |
+
}
|
src/lib/src/Modules/Lockdown/Options.php
CHANGED
@@ -6,4 +6,32 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
6 |
|
7 |
class Options extends Base\ShieldOptions {
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
}
|
6 |
|
7 |
class Options extends Base\ShieldOptions {
|
8 |
|
9 |
+
/**
|
10 |
+
* @return string[]
|
11 |
+
*/
|
12 |
+
public function getRestApiAnonymousExclusions() {
|
13 |
+
$ex = $this->getOpt( 'api_namespace_exclusions' );
|
14 |
+
return array_merge( $this->getDef( 'default_restapi_exclusions' ), is_array( $ex ) ? $ex : [] );
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @return bool
|
19 |
+
*/
|
20 |
+
public function isOptFileEditingDisabled() {
|
21 |
+
return $this->isOpt( 'disable_file_editing', 'Y' );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @return bool
|
26 |
+
*/
|
27 |
+
public function isRestApiAnonymousAccessDisabled() {
|
28 |
+
return $this->isOpt( 'disable_anonymous_restapi', 'Y' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @return bool
|
33 |
+
*/
|
34 |
+
public function isXmlrpcDisabled() {
|
35 |
+
return $this->isOpt( 'disable_xmlrpc', 'Y' );
|
36 |
+
}
|
37 |
}
|
src/lib/src/Modules/Lockdown/Strings.php
CHANGED
@@ -18,13 +18,13 @@ class Strings extends Base\Strings {
|
|
18 |
}
|
19 |
|
20 |
/**
|
21 |
-
* @param string $
|
22 |
* @return array
|
23 |
* @throws \Exception
|
24 |
*/
|
25 |
-
public function getSectionStrings( $
|
26 |
|
27 |
-
switch ( $
|
28 |
|
29 |
case 'section_enable_plugin_feature_wordpress_lockdown' :
|
30 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
@@ -64,7 +64,7 @@ class Strings extends Base\Strings {
|
|
64 |
break;
|
65 |
|
66 |
default:
|
67 |
-
return parent::getSectionStrings( $
|
68 |
}
|
69 |
|
70 |
return [
|
@@ -75,15 +75,15 @@ class Strings extends Base\Strings {
|
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
-
* @param string $
|
79 |
* @return array
|
80 |
* @throws \Exception
|
81 |
*/
|
82 |
-
public function getOptionStrings( $
|
83 |
|
84 |
$sModName = $this->getMod()->getMainFeatureName();
|
85 |
|
86 |
-
switch ( $
|
87 |
|
88 |
case 'enable_lockdown' :
|
89 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -132,6 +132,17 @@ class Strings extends Base\Strings {
|
|
132 |
$sDescription = __( 'Remove a meta tag from your WordPress pages that publicly displays that your site is WordPress and its current version.', 'wp-simple-firewall' );
|
133 |
break;
|
134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
case 'block_author_discovery' :
|
136 |
$sName = __( 'Block Username Fishing', 'wp-simple-firewall' );
|
137 |
$sSummary = __( 'Block the ability to discover WordPress usernames based on author IDs', 'wp-simple-firewall' );
|
@@ -140,7 +151,7 @@ class Strings extends Base\Strings {
|
|
140 |
break;
|
141 |
|
142 |
default:
|
143 |
-
return parent::getOptionStrings( $
|
144 |
}
|
145 |
|
146 |
return [
|
18 |
}
|
19 |
|
20 |
/**
|
21 |
+
* @param string $section
|
22 |
* @return array
|
23 |
* @throws \Exception
|
24 |
*/
|
25 |
+
public function getSectionStrings( $section ) {
|
26 |
|
27 |
+
switch ( $section ) {
|
28 |
|
29 |
case 'section_enable_plugin_feature_wordpress_lockdown' :
|
30 |
$sTitleShort = sprintf( '%s/%s', __( 'On', 'wp-simple-firewall' ), __( 'Off', 'wp-simple-firewall' ) );
|
64 |
break;
|
65 |
|
66 |
default:
|
67 |
+
return parent::getSectionStrings( $section );
|
68 |
}
|
69 |
|
70 |
return [
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
+
* @param string $key
|
79 |
* @return array
|
80 |
* @throws \Exception
|
81 |
*/
|
82 |
+
public function getOptionStrings( $key ) {
|
83 |
|
84 |
$sModName = $this->getMod()->getMainFeatureName();
|
85 |
|
86 |
+
switch ( $key ) {
|
87 |
|
88 |
case 'enable_lockdown' :
|
89 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
132 |
$sDescription = __( 'Remove a meta tag from your WordPress pages that publicly displays that your site is WordPress and its current version.', 'wp-simple-firewall' );
|
133 |
break;
|
134 |
|
135 |
+
case 'clean_wp_rubbish' :
|
136 |
+
$sName = __( 'Clean WP Files', 'wp-simple-firewall' );
|
137 |
+
$sSummary = __( 'Automatically Delete Unnecessary WP Files', 'wp-simple-firewall' );
|
138 |
+
$sDescription = [
|
139 |
+
__( "Automatically delete WordPress files that aren't necessary.", 'wp-simple-firewall' ),
|
140 |
+
__( "The cleanup process runs once each day.", 'wp-simple-firewall' ),
|
141 |
+
sprintf( '%s: <code>%s</code>', __( 'Files Deleted', 'wp-simple-firewall' ),
|
142 |
+
implode( '</code><code>', [ 'wp-config-sample.php', 'readme.html', 'license.txt' ] ) )
|
143 |
+
];
|
144 |
+
break;
|
145 |
+
|
146 |
case 'block_author_discovery' :
|
147 |
$sName = __( 'Block Username Fishing', 'wp-simple-firewall' );
|
148 |
$sSummary = __( 'Block the ability to discover WordPress usernames based on author IDs', 'wp-simple-firewall' );
|
151 |
break;
|
152 |
|
153 |
default:
|
154 |
+
return parent::getOptionStrings( $key );
|
155 |
}
|
156 |
|
157 |
return [
|
src/lib/src/Modules/Lockdown/UI.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Lockdown;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
|
7 |
+
class UI extends Base\ShieldUI {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getInsightsConfigCardData() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_Lockdown $mod */
|
14 |
+
$mod = $this->getMod();
|
15 |
+
/** @var Options $opts */
|
16 |
+
$opts = $this->getOptions();
|
17 |
+
|
18 |
+
$data = [
|
19 |
+
'strings' => [
|
20 |
+
'title' => __( 'WordPress Lockdown', 'wp-simple-firewall' ),
|
21 |
+
'sub' => __( 'Restrict WP Functionality e.g. XMLRPC & REST API', 'wp-simple-firewall' ),
|
22 |
+
],
|
23 |
+
'key_opts' => [],
|
24 |
+
'href_options' => $mod->getUrl_AdminPage()
|
25 |
+
];
|
26 |
+
|
27 |
+
if ( !$mod->isModOptEnabled() ) {
|
28 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$bEditingDisabled = $opts->isOptFileEditingDisabled() || !current_user_can( 'edit_plugins' );
|
32 |
+
$data[ 'key_opts' ][ 'editing' ] = [
|
33 |
+
'name' => __( 'File Editing via WP', 'wp-simple-firewall' ),
|
34 |
+
'enabled' => $bEditingDisabled,
|
35 |
+
'summary' => $bEditingDisabled ?
|
36 |
+
__( 'File editing is disabled', 'wp-simple-firewall' )
|
37 |
+
: __( "File editing is permitted through WP admin", 'wp-simple-firewall' ),
|
38 |
+
'weight' => 2,
|
39 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'disable_file_editing' ),
|
40 |
+
];
|
41 |
+
|
42 |
+
$bXml = $opts->isXmlrpcDisabled();
|
43 |
+
$data[ 'key_opts' ][ 'xml' ] = [
|
44 |
+
'name' => __( 'XML-RPC', 'wp-simple-firewall' ),
|
45 |
+
'enabled' => $bXml,
|
46 |
+
'summary' => $bXml ?
|
47 |
+
__( 'XML-RPC is disabled', 'wp-simple-firewall' )
|
48 |
+
: __( "XML-RPC is not blocked", 'wp-simple-firewall' ),
|
49 |
+
'weight' => 1,
|
50 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'disable_xmlrpc' ),
|
51 |
+
];
|
52 |
+
|
53 |
+
$bApi = $opts->isRestApiAnonymousAccessDisabled();
|
54 |
+
$data[ 'key_opts' ][ 'api' ] = [
|
55 |
+
'name' => __( 'REST API', 'wp-simple-firewall' ),
|
56 |
+
'enabled' => $bApi,
|
57 |
+
'summary' => $bApi ?
|
58 |
+
__( 'Anonymous REST API is disabled', 'wp-simple-firewall' )
|
59 |
+
: __( "Anonymous REST API is allowed", 'wp-simple-firewall' ),
|
60 |
+
'weight' => 1,
|
61 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'disable_anonymous_restapi' ),
|
62 |
+
];
|
63 |
+
}
|
64 |
+
|
65 |
+
return $data;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @return array
|
70 |
+
*/
|
71 |
+
public function getInsightsNoticesData() {
|
72 |
+
/** @var \ICWP_WPSF_FeatureHandler_Lockdown $mod */
|
73 |
+
$mod = $this->getMod();
|
74 |
+
/** @var Options $opts */
|
75 |
+
$opts = $this->getOptions();
|
76 |
+
|
77 |
+
$notices = [
|
78 |
+
'title' => __( 'WP Lockdown', 'wp-simple-firewall' ),
|
79 |
+
'messages' => []
|
80 |
+
];
|
81 |
+
|
82 |
+
{ //edit plugins
|
83 |
+
$bEditingDisabled = $opts->isOptFileEditingDisabled() || !current_user_can( 'edit_plugins' );
|
84 |
+
if ( !$bEditingDisabled ) { //assumes current user is admin
|
85 |
+
$notices[ 'messages' ][ 'disallow_file_edit' ] = [
|
86 |
+
'title' => __( 'File Editing via WP', 'wp-simple-firewall' ),
|
87 |
+
'message' => __( 'Direct editing of plugin/theme files is permitted.', 'wp-simple-firewall' ),
|
88 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'disable_file_editing' ),
|
89 |
+
'action' => sprintf( __( 'Go To %s', 'wp-simple-firewall' ), __( 'Options', 'wp-simple-firewall' ) ),
|
90 |
+
'rec' => __( 'WP Plugin file editing should be disabled.', 'wp-simple-firewall' )
|
91 |
+
];
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
return $notices;
|
96 |
+
}
|
97 |
+
}
|
src/lib/src/Modules/LoginGuard/AjaxHandler.php
CHANGED
@@ -9,12 +9,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
11 |
/**
|
12 |
-
* @param string $
|
13 |
* @return array
|
14 |
*/
|
15 |
-
protected function processAjaxAction( $
|
16 |
|
17 |
-
switch ( $
|
18 |
case 'gen_backup_codes':
|
19 |
$aResponse = $this->ajaxExec_GenBackupCodes();
|
20 |
break;
|
@@ -40,7 +40,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
40 |
break;
|
41 |
|
42 |
default:
|
43 |
-
$aResponse = parent::processAjaxAction( $
|
44 |
}
|
45 |
|
46 |
return $aResponse;
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
10 |
|
11 |
/**
|
12 |
+
* @param string $action
|
13 |
* @return array
|
14 |
*/
|
15 |
+
protected function processAjaxAction( $action ) {
|
16 |
|
17 |
+
switch ( $action ) {
|
18 |
case 'gen_backup_codes':
|
19 |
$aResponse = $this->ajaxExec_GenBackupCodes();
|
20 |
break;
|
40 |
break;
|
41 |
|
42 |
default:
|
43 |
+
$aResponse = parent::processAjaxAction( $action );
|
44 |
}
|
45 |
|
46 |
return $aResponse;
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/AntibotSetup.php
CHANGED
@@ -3,10 +3,9 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot;
|
|
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\Captcha\CaptchaConfigVO;
|
9 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\TestCacheDirWrite;
|
10 |
use FernleafSystems\Wordpress\Services\Services;
|
11 |
|
12 |
class AntibotSetup {
|
@@ -24,31 +23,31 @@ class AntibotSetup {
|
|
24 |
}
|
25 |
|
26 |
private function run() {
|
27 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $
|
28 |
-
$
|
29 |
-
/** @var LoginGuard\Options $
|
30 |
-
$
|
31 |
|
32 |
$aProtectionProviders = [];
|
33 |
-
if ( $
|
34 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\CoolDown() )
|
35 |
-
->setMod( $
|
36 |
}
|
37 |
|
38 |
-
if ( $
|
39 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\GaspJs() )
|
40 |
-
->setMod( $
|
41 |
}
|
42 |
|
43 |
-
if ( $
|
44 |
-
$oCfg = $
|
45 |
if ( $oCfg->provider === CaptchaConfigVO::PROV_GOOGLE_RECAP2 ) {
|
46 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\GoogleRecaptcha() )
|
47 |
-
->setMod( $
|
48 |
}
|
49 |
elseif ( $oCfg->provider === CaptchaConfigVO::PROV_HCAPTCHA ) {
|
50 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\HCaptcha() )
|
51 |
-
->setMod( $
|
52 |
}
|
53 |
}
|
54 |
|
@@ -85,13 +84,16 @@ class AntibotSetup {
|
|
85 |
if ( @class_exists( 'WooCommerce' ) ) {
|
86 |
$aFormProviders[] = new AntiBot\FormProviders\WooCommerce();
|
87 |
}
|
|
|
|
|
|
|
88 |
if ( false && @class_exists( 'UserRegistration' ) && @function_exists( 'UR' ) ) {
|
89 |
$aFormProviders[] = new AntiBot\FormProviders\UserRegistration();
|
90 |
}
|
91 |
}
|
92 |
|
93 |
foreach ( $aFormProviders as $oForm ) {
|
94 |
-
$oForm->setMod( $
|
95 |
}
|
96 |
}
|
97 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\Captcha\CaptchaConfigVO;
|
|
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
10 |
|
11 |
class AntibotSetup {
|
23 |
}
|
24 |
|
25 |
private function run() {
|
26 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $mod */
|
27 |
+
$mod = $this->getMod();
|
28 |
+
/** @var LoginGuard\Options $opts */
|
29 |
+
$opts = $this->getOptions();
|
30 |
|
31 |
$aProtectionProviders = [];
|
32 |
+
if ( $opts->isEnabledCooldown() && $mod->canCacheDirWrite() ) {
|
33 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\CoolDown() )
|
34 |
+
->setMod( $mod );
|
35 |
}
|
36 |
|
37 |
+
if ( $opts->isEnabledGaspCheck() ) {
|
38 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\GaspJs() )
|
39 |
+
->setMod( $mod );
|
40 |
}
|
41 |
|
42 |
+
if ( $mod->isEnabledCaptcha() ) {
|
43 |
+
$oCfg = $mod->getCaptchaCfg();
|
44 |
if ( $oCfg->provider === CaptchaConfigVO::PROV_GOOGLE_RECAP2 ) {
|
45 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\GoogleRecaptcha() )
|
46 |
+
->setMod( $mod );
|
47 |
}
|
48 |
elseif ( $oCfg->provider === CaptchaConfigVO::PROV_HCAPTCHA ) {
|
49 |
$aProtectionProviders[] = ( new AntiBot\ProtectionProviders\HCaptcha() )
|
50 |
+
->setMod( $mod );
|
51 |
}
|
52 |
}
|
53 |
|
84 |
if ( @class_exists( 'WooCommerce' ) ) {
|
85 |
$aFormProviders[] = new AntiBot\FormProviders\WooCommerce();
|
86 |
}
|
87 |
+
if ( defined( 'WPMEM_VERSION' ) && function_exists( 'wpmem_init' ) ) {
|
88 |
+
$aFormProviders[] = new AntiBot\FormProviders\WPMembers();
|
89 |
+
}
|
90 |
if ( false && @class_exists( 'UserRegistration' ) && @function_exists( 'UR' ) ) {
|
91 |
$aFormProviders[] = new AntiBot\FormProviders\UserRegistration();
|
92 |
}
|
93 |
}
|
94 |
|
95 |
foreach ( $aFormProviders as $oForm ) {
|
96 |
+
$oForm->setMod( $mod )->run();
|
97 |
}
|
98 |
}
|
99 |
}
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/MemberPress.php
CHANGED
@@ -30,7 +30,7 @@ class MemberPress extends BaseFormProvider {
|
|
30 |
* @return array
|
31 |
*/
|
32 |
public function checkLogin( $aErrors ) {
|
33 |
-
if (
|
34 |
try {
|
35 |
$this->setActionToAudit( 'memberpress-login' )
|
36 |
->checkProviders();
|
@@ -47,8 +47,7 @@ class MemberPress extends BaseFormProvider {
|
|
47 |
* @return array
|
48 |
*/
|
49 |
public function checkLostPassword( $aErrors ) {
|
50 |
-
|
51 |
-
if ( !empty( $aErrors ) ) {
|
52 |
try {
|
53 |
$this->setActionToAudit( 'memberpress-lostpassword' )
|
54 |
->checkProviders();
|
@@ -66,7 +65,7 @@ class MemberPress extends BaseFormProvider {
|
|
66 |
* @return string[]
|
67 |
*/
|
68 |
public function checkRegister( $aErrors ) {
|
69 |
-
if (
|
70 |
try {
|
71 |
$this->setActionToAudit( 'memberpress-register' )
|
72 |
->checkProviders();
|
30 |
* @return array
|
31 |
*/
|
32 |
public function checkLogin( $aErrors ) {
|
33 |
+
if ( empty( $aErrors ) ) {
|
34 |
try {
|
35 |
$this->setActionToAudit( 'memberpress-login' )
|
36 |
->checkProviders();
|
47 |
* @return array
|
48 |
*/
|
49 |
public function checkLostPassword( $aErrors ) {
|
50 |
+
if ( empty( $aErrors ) ) {
|
|
|
51 |
try {
|
52 |
$this->setActionToAudit( 'memberpress-lostpassword' )
|
53 |
->checkProviders();
|
65 |
* @return string[]
|
66 |
*/
|
67 |
public function checkRegister( $aErrors ) {
|
68 |
+
if ( empty( $aErrors ) ) {
|
69 |
try {
|
70 |
$this->setActionToAudit( 'memberpress-register' )
|
71 |
->checkProviders();
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WPMembers.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot\FormProviders;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class WPMembers
|
7 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot\FormProviders
|
8 |
+
* https://wordpress.org/plugins/wp-members/
|
9 |
+
*/
|
10 |
+
class WPMembers extends BaseFormProvider {
|
11 |
+
|
12 |
+
protected function register() {
|
13 |
+
add_action( 'wpmem_pre_register_data', [ $this, 'checkRegister' ], 5, 0 );
|
14 |
+
}
|
15 |
+
|
16 |
+
protected function lostpassword() {
|
17 |
+
add_action( 'wpmem_pwdreset_args', [ $this, 'checkLostPassword' ], 5, 1 );
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Again, nowhere to add custom validation so we hack it a little and clear
|
22 |
+
* the argument for user and email and this triggers a failure.
|
23 |
+
* @param array $args
|
24 |
+
* @return array
|
25 |
+
*/
|
26 |
+
public function checkLostPassword( array $args ) {
|
27 |
+
try {
|
28 |
+
$this->setActionToAudit( 'wpmembers-lostpassword' )
|
29 |
+
->checkProviders();
|
30 |
+
}
|
31 |
+
catch ( \Exception $oE ) {
|
32 |
+
$args[ 'user' ] = null;
|
33 |
+
$args[ 'email' ] = null;
|
34 |
+
}
|
35 |
+
return $args;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Offers no direct validation filter, so we jump in right before the DB insert.
|
40 |
+
*/
|
41 |
+
public function checkRegister() {
|
42 |
+
try {
|
43 |
+
$this->setActionToAudit( 'wpmembers-register' )
|
44 |
+
->checkProviders();
|
45 |
+
}
|
46 |
+
catch ( \Exception $oE ) {
|
47 |
+
global $wpmem_themsg;
|
48 |
+
$wpmem_themsg = $oE->getMessage();
|
49 |
+
}
|
50 |
+
}
|
51 |
+
}
|
src/lib/src/Modules/LoginGuard/Lib/AntiBot/ProtectionProviders/GaspJs.php
CHANGED
@@ -70,19 +70,19 @@ class GaspJs extends BaseProtectionProvider {
|
|
70 |
}
|
71 |
|
72 |
public function onWpEnqueueJs() {
|
73 |
-
$
|
74 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $
|
75 |
-
$
|
76 |
/** @var LoginGuard\Options $oOpts */
|
77 |
$oOpts = $this->getOptions();
|
78 |
|
79 |
$sAsset = 'shield-antibot';
|
80 |
-
$sUnique = $
|
81 |
wp_register_script(
|
82 |
$sUnique,
|
83 |
-
$
|
84 |
[ 'jquery' ],
|
85 |
-
$
|
86 |
);
|
87 |
wp_enqueue_script( $sUnique );
|
88 |
|
@@ -92,15 +92,15 @@ class GaspJs extends BaseProtectionProvider {
|
|
92 |
[
|
93 |
'form_selectors' => implode( ',', $oOpts->getAntiBotFormSelectors() ),
|
94 |
'uniq' => preg_replace( '#[^a-zA-Z0-9]#', '', apply_filters( 'icwp_shield_lp_gasp_uniqid', uniqid() ) ),
|
95 |
-
'cbname' => $
|
96 |
'strings' => [
|
97 |
-
'label' => $
|
98 |
-
'alert' => $
|
99 |
'loading' => __( 'Loading', 'wp-simple-firewall' )
|
100 |
],
|
101 |
'flags' => [
|
102 |
'gasp' => $oOpts->isEnabledGaspCheck(),
|
103 |
-
'captcha' => $
|
104 |
]
|
105 |
]
|
106 |
);
|
70 |
}
|
71 |
|
72 |
public function onWpEnqueueJs() {
|
73 |
+
$con = $this->getCon();
|
74 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $mod */
|
75 |
+
$mod = $this->getMod();
|
76 |
/** @var LoginGuard\Options $oOpts */
|
77 |
$oOpts = $this->getOptions();
|
78 |
|
79 |
$sAsset = 'shield-antibot';
|
80 |
+
$sUnique = $con->prefix( $sAsset );
|
81 |
wp_register_script(
|
82 |
$sUnique,
|
83 |
+
$con->getPluginUrl_Js( $sAsset ),
|
84 |
[ 'jquery' ],
|
85 |
+
$con->getVersion()
|
86 |
);
|
87 |
wp_enqueue_script( $sUnique );
|
88 |
|
92 |
[
|
93 |
'form_selectors' => implode( ',', $oOpts->getAntiBotFormSelectors() ),
|
94 |
'uniq' => preg_replace( '#[^a-zA-Z0-9]#', '', apply_filters( 'icwp_shield_lp_gasp_uniqid', uniqid() ) ),
|
95 |
+
'cbname' => $mod->getGaspKey(),
|
96 |
'strings' => [
|
97 |
+
'label' => $mod->getTextImAHuman(),
|
98 |
+
'alert' => $mod->getTextPleaseCheckBox(),
|
99 |
'loading' => __( 'Loading', 'wp-simple-firewall' )
|
100 |
],
|
101 |
'flags' => [
|
102 |
'gasp' => $oOpts->isEnabledGaspCheck(),
|
103 |
+
'captcha' => $mod->isEnabledCaptcha(),
|
104 |
]
|
105 |
]
|
106 |
);
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php
CHANGED
@@ -11,8 +11,6 @@ class LoginIntentPage {
|
|
11 |
|
12 |
use MfaControllerConsumer;
|
13 |
|
14 |
-
/**
|
15 |
-
*/
|
16 |
public function loadPage() {
|
17 |
echo $this->renderPage();
|
18 |
}
|
@@ -22,25 +20,25 @@ class LoginIntentPage {
|
|
22 |
*/
|
23 |
public function renderForm() {
|
24 |
$oIC = $this->getMfaCon();
|
25 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $
|
26 |
-
$
|
27 |
-
/** @var LoginGuard\Options $
|
28 |
-
$
|
29 |
-
$
|
30 |
-
$
|
31 |
-
$
|
32 |
-
|
33 |
-
$oNotice = $
|
34 |
if ( $oNotice instanceof NoticeVO ) {
|
35 |
$sMessage = $oNotice->render_data[ 'message' ];
|
36 |
}
|
37 |
else {
|
38 |
-
$sMessage = $
|
39 |
__( 'Please supply all authentication codes', 'wp-simple-firewall' )
|
40 |
: __( 'Please supply at least 1 authentication code', 'wp-simple-firewall' );
|
41 |
}
|
42 |
|
43 |
-
$sReferUrl = $
|
44 |
if ( strpos( $sReferUrl, '?' ) ) {
|
45 |
list( $sReferUrl, $sReferQuery ) = explode( '?', $sReferUrl, 2 );
|
46 |
}
|
@@ -56,17 +54,17 @@ class LoginIntentPage {
|
|
56 |
}
|
57 |
}
|
58 |
if ( empty( $sRedirectTo ) ) {
|
59 |
-
$sRedirectTo = rawurlencode( $
|
60 |
}
|
61 |
|
62 |
-
$sCancelHref = $
|
63 |
if ( empty( $sCancelHref ) && Services::Data()->isValidWebUrl( $sReferUrl ) ) {
|
64 |
$sCancelHref = parse_url( $sReferUrl, PHP_URL_PATH );
|
65 |
}
|
66 |
|
67 |
-
$nMfaSkip = (int)( $
|
68 |
-
$nTimeRemaining = $
|
69 |
-
$
|
70 |
'strings' => [
|
71 |
'cancel' => __( 'Cancel Login', 'wp-simple-firewall' ),
|
72 |
'time_remaining' => __( 'Time Remaining', 'wp-simple-firewall' ),
|
@@ -89,21 +87,25 @@ class LoginIntentPage {
|
|
89 |
) ),
|
90 |
'time_remaining' => $nTimeRemaining,
|
91 |
'message_type' => 'info',
|
92 |
-
'login_intent_flag' => $
|
93 |
],
|
94 |
'hrefs' => [
|
95 |
-
'form_action' => parse_url( $
|
96 |
'redirect_to' => $sRedirectTo,
|
97 |
'cancel_href' => $sCancelHref
|
98 |
],
|
99 |
'flags' => [
|
100 |
-
'can_skip_mfa' => $
|
101 |
-
'show_branded_links' => !$
|
102 |
]
|
103 |
];
|
104 |
|
105 |
-
return $
|
106 |
-
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
|
109 |
/**
|
@@ -162,6 +164,7 @@ class LoginIntentPage {
|
|
162 |
}
|
163 |
|
164 |
return $oMod->renderTemplate( '/pages/login_intent/index.twig',
|
165 |
-
Services::DataManipulation()->mergeArraysRecursive(
|
|
|
166 |
}
|
167 |
}
|
11 |
|
12 |
use MfaControllerConsumer;
|
13 |
|
|
|
|
|
14 |
public function loadPage() {
|
15 |
echo $this->renderPage();
|
16 |
}
|
20 |
*/
|
21 |
public function renderForm() {
|
22 |
$oIC = $this->getMfaCon();
|
23 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $mod */
|
24 |
+
$mod = $oIC->getMod();
|
25 |
+
/** @var LoginGuard\Options $opts */
|
26 |
+
$opts = $oIC->getOptions();
|
27 |
+
$con = $oIC->getCon();
|
28 |
+
$req = Services::Request();
|
29 |
+
$WP = Services::WpGeneral();
|
30 |
+
|
31 |
+
$oNotice = $con->getAdminNotices()->getFlashNotice();
|
32 |
if ( $oNotice instanceof NoticeVO ) {
|
33 |
$sMessage = $oNotice->render_data[ 'message' ];
|
34 |
}
|
35 |
else {
|
36 |
+
$sMessage = $opts->isChainedAuth() ?
|
37 |
__( 'Please supply all authentication codes', 'wp-simple-firewall' )
|
38 |
: __( 'Please supply at least 1 authentication code', 'wp-simple-firewall' );
|
39 |
}
|
40 |
|
41 |
+
$sReferUrl = $req->server( 'HTTP_REFERER', '' );
|
42 |
if ( strpos( $sReferUrl, '?' ) ) {
|
43 |
list( $sReferUrl, $sReferQuery ) = explode( '?', $sReferUrl, 2 );
|
44 |
}
|
54 |
}
|
55 |
}
|
56 |
if ( empty( $sRedirectTo ) ) {
|
57 |
+
$sRedirectTo = rawurlencode( $req->post( 'redirect_to', $req->getUri() ) );
|
58 |
}
|
59 |
|
60 |
+
$sCancelHref = $req->post( 'cancel_href', '' );
|
61 |
if ( empty( $sCancelHref ) && Services::Data()->isValidWebUrl( $sReferUrl ) ) {
|
62 |
$sCancelHref = parse_url( $sReferUrl, PHP_URL_PATH );
|
63 |
}
|
64 |
|
65 |
+
$nMfaSkip = (int)( $opts->getMfaSkip()/DAY_IN_SECONDS );
|
66 |
+
$nTimeRemaining = $mod->getSession()->login_intent_expires_at - $req->ts();
|
67 |
+
$data = [
|
68 |
'strings' => [
|
69 |
'cancel' => __( 'Cancel Login', 'wp-simple-firewall' ),
|
70 |
'time_remaining' => __( 'Time Remaining', 'wp-simple-firewall' ),
|
87 |
) ),
|
88 |
'time_remaining' => $nTimeRemaining,
|
89 |
'message_type' => 'info',
|
90 |
+
'login_intent_flag' => $mod->getLoginIntentRequestFlag(),
|
91 |
],
|
92 |
'hrefs' => [
|
93 |
+
'form_action' => parse_url( $WP->getAdminUrl( '', true ), PHP_URL_PATH ),
|
94 |
'redirect_to' => $sRedirectTo,
|
95 |
'cancel_href' => $sCancelHref
|
96 |
],
|
97 |
'flags' => [
|
98 |
+
'can_skip_mfa' => $opts->isMfaSkip(),
|
99 |
+
'show_branded_links' => !$mod->isWlEnabled(), // white label mitigation
|
100 |
]
|
101 |
];
|
102 |
|
103 |
+
return $mod->renderTemplate(
|
104 |
+
'/snippets/login_intent/form.twig',
|
105 |
+
Services::DataManipulation()->mergeArraysRecursive(
|
106 |
+
$mod->getUIHandler()->getBaseDisplayData(), $data ),
|
107 |
+
true
|
108 |
+
);
|
109 |
}
|
110 |
|
111 |
/**
|
164 |
}
|
165 |
|
166 |
return $oMod->renderTemplate( '/pages/login_intent/index.twig',
|
167 |
+
Services::DataManipulation()->mergeArraysRecursive(
|
168 |
+
$oMod->getUIHandler()->getBaseDisplayData(), $aDisplayData ), true );
|
169 |
}
|
170 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Profiles/CustomForms.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Profiles;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\OneTimeExecute;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\MfaControllerConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider\BaseProvider;
|
8 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Consumer\WpUserConsumer;
|
9 |
+
|
10 |
+
class CustomForms {
|
11 |
+
|
12 |
+
use OneTimeExecute;
|
13 |
+
use MfaControllerConsumer;
|
14 |
+
use WpUserConsumer;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var BaseProvider[]
|
18 |
+
*/
|
19 |
+
private $aWorkingProviders = [];
|
20 |
+
|
21 |
+
public function run() {
|
22 |
+
// Enqueue Javascript.
|
23 |
+
add_action( 'wp_enqueue_scripts', function () {
|
24 |
+
$this->enqueueAssets();
|
25 |
+
}, 0 );
|
26 |
+
add_action( 'wp_footer', function () {
|
27 |
+
$this->maybeDequeueAssets();
|
28 |
+
}, 0 );
|
29 |
+
add_action( 'custom_profile_form_output', function ( array $aProviders ) {
|
30 |
+
$this->renderCustomProfileFormOutput( $aProviders );
|
31 |
+
} );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param string[] $aPs - list of limited provider slugs
|
36 |
+
*/
|
37 |
+
private function renderCustomProfileFormOutput( array $aPs ) {
|
38 |
+
$oMC = $this->getMfaCon();
|
39 |
+
$oUser = $this->getWpUser();
|
40 |
+
|
41 |
+
$aProviders = $oMC->getProvidersForUser( $oUser, true );
|
42 |
+
if ( !empty( $aPs ) ) {
|
43 |
+
$aProviders = array_filter(
|
44 |
+
$aProviders,
|
45 |
+
function ( $oP ) use ( $aPs ) {
|
46 |
+
return in_array( $oP::SLUG, array_map( 'strtolower', $aPs ) );
|
47 |
+
}
|
48 |
+
);
|
49 |
+
}
|
50 |
+
|
51 |
+
if ( !empty( $aProviders ) ) {
|
52 |
+
$this->aWorkingProviders = $aProviders;
|
53 |
+
foreach ( $aProviders as $oP ) {
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
private function enqueueAssets() {
|
59 |
+
//enqueue in footer
|
60 |
+
}
|
61 |
+
|
62 |
+
private function maybeDequeueAssets() {
|
63 |
+
if ( empty( $this->aWorkingProviders ) ) {
|
64 |
+
//dequeue
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
src/lib/src/Modules/LoginGuard/Strings.php
CHANGED
@@ -55,13 +55,13 @@ class Strings extends Base\Strings {
|
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
-
* @param string $
|
59 |
* @return array
|
60 |
* @throws \Exception
|
61 |
*/
|
62 |
-
public function getSectionStrings( $
|
63 |
|
64 |
-
switch ( $
|
65 |
|
66 |
case 'section_enable_plugin_feature_login_protection' :
|
67 |
$sTitle = sprintf( __( 'Enable Module: %s', 'wp-simple-firewall' ), $this->getMod()
|
@@ -129,7 +129,7 @@ class Strings extends Base\Strings {
|
|
129 |
break;
|
130 |
|
131 |
default:
|
132 |
-
return parent::getSectionStrings( $
|
133 |
}
|
134 |
|
135 |
return [
|
@@ -140,16 +140,16 @@ class Strings extends Base\Strings {
|
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
-
* @param string $
|
144 |
* @return array
|
145 |
* @throws \Exception
|
146 |
*/
|
147 |
-
public function getOptionStrings( $
|
148 |
-
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $
|
149 |
-
$
|
150 |
-
$sModName = $
|
151 |
|
152 |
-
switch ( $
|
153 |
|
154 |
case 'enable_login_protect' :
|
155 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
@@ -249,7 +249,7 @@ class Strings extends Base\Strings {
|
|
249 |
$sSummary = __( 'Limit account access requests to every X seconds', 'wp-simple-firewall' );
|
250 |
$sDescription = __( 'WordPress will process only ONE account access attempt per number of seconds specified.', 'wp-simple-firewall' )
|
251 |
.'<br />'.__( 'Zero (0) turns this off.', 'wp-simple-firewall' )
|
252 |
-
.' '.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $
|
253 |
->getOptDefault( 'login_limit_interval' ) );
|
254 |
break;
|
255 |
|
@@ -307,14 +307,14 @@ class Strings extends Base\Strings {
|
|
307 |
$sName = __( 'GASP Checkbox Text', 'wp-simple-firewall' );
|
308 |
$sSummary = __( 'The User Message Displayed Next To The GASP Checkbox', 'wp-simple-firewall' );
|
309 |
$sDescription = __( "You can change the text displayed to the user beside the checkbox if you need a custom message.", 'wp-simple-firewall' )
|
310 |
-
.'<br />'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $
|
311 |
break;
|
312 |
|
313 |
case 'text_pleasecheckbox' :
|
314 |
$sName = __( 'GASP Alert Text', 'wp-simple-firewall' );
|
315 |
$sSummary = __( "The Message Displayed If The User Doesn't Check The Box", 'wp-simple-firewall' );
|
316 |
$sDescription = __( "You can change the text displayed to the user in the alert message if they don't check the box.", 'wp-simple-firewall' )
|
317 |
-
.'<br />'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $
|
318 |
break;
|
319 |
|
320 |
// removed 9.0
|
@@ -325,7 +325,7 @@ class Strings extends Base\Strings {
|
|
325 |
break;
|
326 |
|
327 |
default:
|
328 |
-
return parent::getOptionStrings( $
|
329 |
}
|
330 |
|
331 |
return [
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
+
* @param string $section
|
59 |
* @return array
|
60 |
* @throws \Exception
|
61 |
*/
|
62 |
+
public function getSectionStrings( $section ) {
|
63 |
|
64 |
+
switch ( $section ) {
|
65 |
|
66 |
case 'section_enable_plugin_feature_login_protection' :
|
67 |
$sTitle = sprintf( __( 'Enable Module: %s', 'wp-simple-firewall' ), $this->getMod()
|
129 |
break;
|
130 |
|
131 |
default:
|
132 |
+
return parent::getSectionStrings( $section );
|
133 |
}
|
134 |
|
135 |
return [
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
+
* @param string $key
|
144 |
* @return array
|
145 |
* @throws \Exception
|
146 |
*/
|
147 |
+
public function getOptionStrings( $key ) {
|
148 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $mod */
|
149 |
+
$mod = $this->getMod();
|
150 |
+
$sModName = $mod->getMainFeatureName();
|
151 |
|
152 |
+
switch ( $key ) {
|
153 |
|
154 |
case 'enable_login_protect' :
|
155 |
$sName = sprintf( __( 'Enable %s Module', 'wp-simple-firewall' ), $sModName );
|
249 |
$sSummary = __( 'Limit account access requests to every X seconds', 'wp-simple-firewall' );
|
250 |
$sDescription = __( 'WordPress will process only ONE account access attempt per number of seconds specified.', 'wp-simple-firewall' )
|
251 |
.'<br />'.__( 'Zero (0) turns this off.', 'wp-simple-firewall' )
|
252 |
+
.' '.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $this->getOptions()
|
253 |
->getOptDefault( 'login_limit_interval' ) );
|
254 |
break;
|
255 |
|
307 |
$sName = __( 'GASP Checkbox Text', 'wp-simple-firewall' );
|
308 |
$sSummary = __( 'The User Message Displayed Next To The GASP Checkbox', 'wp-simple-firewall' );
|
309 |
$sDescription = __( "You can change the text displayed to the user beside the checkbox if you need a custom message.", 'wp-simple-firewall' )
|
310 |
+
.'<br />'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $mod->getTextOptDefault( 'text_imahuman' ) );
|
311 |
break;
|
312 |
|
313 |
case 'text_pleasecheckbox' :
|
314 |
$sName = __( 'GASP Alert Text', 'wp-simple-firewall' );
|
315 |
$sSummary = __( "The Message Displayed If The User Doesn't Check The Box", 'wp-simple-firewall' );
|
316 |
$sDescription = __( "You can change the text displayed to the user in the alert message if they don't check the box.", 'wp-simple-firewall' )
|
317 |
+
.'<br />'.sprintf( '%s: %s', __( 'Default', 'wp-simple-firewall' ), $mod->getTextOptDefault( 'text_pleasecheckbox' ) );
|
318 |
break;
|
319 |
|
320 |
// removed 9.0
|
325 |
break;
|
326 |
|
327 |
default:
|
328 |
+
return parent::getOptionStrings( $key );
|
329 |
}
|
330 |
|
331 |
return [
|
src/lib/src/Modules/LoginGuard/UI.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
|
7 |
+
class UI extends Base\ShieldUI {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function getInsightsConfigCardData() {
|
13 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $mod */
|
14 |
+
$mod = $this->getMod();
|
15 |
+
/** @var Options $opts */
|
16 |
+
$opts = $this->getOptions();
|
17 |
+
|
18 |
+
$data = [
|
19 |
+
'strings' => [
|
20 |
+
'title' => __( 'Login Guard', 'wp-simple-firewall' ),
|
21 |
+
'sub' => __( 'Brute Force Protection & Identity Verification', 'wp-simple-firewall' ),
|
22 |
+
],
|
23 |
+
'key_opts' => [],
|
24 |
+
'href_options' => $mod->getUrl_AdminPage()
|
25 |
+
];
|
26 |
+
|
27 |
+
if ( !$mod->isModOptEnabled() ) {
|
28 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
$bHasBotCheck = $opts->isEnabledGaspCheck() || $mod->isEnabledCaptcha();
|
32 |
+
|
33 |
+
$bBotLogin = $bHasBotCheck && $opts->isProtectLogin();
|
34 |
+
$bBotRegister = $bHasBotCheck && $opts->isProtectRegister();
|
35 |
+
$bBotPassword = $bHasBotCheck && $opts->isProtectLostPassword();
|
36 |
+
$data[ 'key_opts' ][ 'bot_login' ] = [
|
37 |
+
'name' => __( 'Brute Force Login', 'wp-simple-firewall' ),
|
38 |
+
'enabled' => $bBotLogin,
|
39 |
+
'summary' => $bBotLogin ?
|
40 |
+
__( 'Login forms are protected against bot attacks', 'wp-simple-firewall' )
|
41 |
+
: __( 'Login forms are not protected against brute force bot attacks', 'wp-simple-firewall' ),
|
42 |
+
'weight' => 2,
|
43 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'bot_protection_locations' ),
|
44 |
+
];
|
45 |
+
$data[ 'key_opts' ][ 'bot_register' ] = [
|
46 |
+
'name' => __( 'Bot User Register', 'wp-simple-firewall' ),
|
47 |
+
'enabled' => $bBotRegister,
|
48 |
+
'summary' => $bBotRegister ?
|
49 |
+
__( 'Registration forms are protected against bot attacks', 'wp-simple-firewall' )
|
50 |
+
: __( 'Registration forms are not protected against automated bots', 'wp-simple-firewall' ),
|
51 |
+
'weight' => 2,
|
52 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'bot_protection_locations' ),
|
53 |
+
];
|
54 |
+
$data[ 'key_opts' ][ 'bot_password' ] = [
|
55 |
+
'name' => __( 'Brute Force Lost Password', 'wp-simple-firewall' ),
|
56 |
+
'enabled' => $bBotPassword,
|
57 |
+
'summary' => $bBotPassword ?
|
58 |
+
__( 'Lost Password forms are protected against bot attacks', 'wp-simple-firewall' )
|
59 |
+
: __( 'Lost Password forms are not protected against automated bots', 'wp-simple-firewall' ),
|
60 |
+
'weight' => 2,
|
61 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'bot_protection_locations' ),
|
62 |
+
];
|
63 |
+
|
64 |
+
$bHas2Fa = $opts->isEmailAuthenticationActive()
|
65 |
+
|| $opts->isEnabledGoogleAuthenticator() || $opts->isEnabledYubikey();
|
66 |
+
$data[ 'key_opts' ][ '2fa' ] = [
|
67 |
+
'name' => __( 'Identity Verification', 'wp-simple-firewall' ),
|
68 |
+
'enabled' => $bHas2Fa,
|
69 |
+
'summary' => $bHas2Fa ?
|
70 |
+
__( 'At least 1 2FA option is enabled', 'wp-simple-firewall' )
|
71 |
+
: __( 'No 2FA options, such as Google Authenticator, are active', 'wp-simple-firewall' ),
|
72 |
+
'weight' => 2,
|
73 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_2fa_email' ),
|
74 |
+
];
|
75 |
+
}
|
76 |
+
|
77 |
+
return $data;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @param string $section
|
82 |
+
* @return array
|
83 |
+
*/
|
84 |
+
protected function getSectionWarnings( $section ) {
|
85 |
+
$aWarnings = [];
|
86 |
+
|
87 |
+
if ( $section == 'section_brute_force_login_protection' && !$this->getCon()->isPremiumActive() ) {
|
88 |
+
$sIntegration = $this->getPremiumOnlyIntegration();
|
89 |
+
if ( !empty( $sIntegration ) ) {
|
90 |
+
$aWarnings[] = sprintf( __( 'Support for login protection with %s is a Pro-only feature.', 'wp-simple-firewall' ), $sIntegration );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
if ( $section == 'section_2fa_email' ) {
|
95 |
+
$aWarnings[] =
|
96 |
+
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
97 |
+
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
98 |
+
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', __( 'Learn More.', 'wp-simple-firewall' ) );
|
99 |
+
}
|
100 |
+
|
101 |
+
return $aWarnings;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
private function getPremiumOnlyIntegration() {
|
108 |
+
$aIntegrations = [
|
109 |
+
'WooCommerce' => 'WooCommerce',
|
110 |
+
'Easy_Digital_Downloads' => 'Easy Digital Downloads',
|
111 |
+
'BuddyPress' => 'BuddyPress',
|
112 |
+
];
|
113 |
+
|
114 |
+
$sIntegration = '';
|
115 |
+
foreach ( $aIntegrations as $classToIntegrate => $sName ) {
|
116 |
+
if ( class_exists( $classToIntegrate ) ) {
|
117 |
+
$sIntegration = $sName;
|
118 |
+
break;
|
119 |
+
}
|
120 |
+
}
|
121 |
+
return $sIntegration;
|
122 |
+
}
|
123 |
+
}
|
src/lib/src/Modules/Plugin/AdminNotices.php
CHANGED
@@ -28,6 +28,10 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
28 |
$this->buildNotice_PluginDisabled( $oNotice );
|
29 |
break;
|
30 |
|
|
|
|
|
|
|
|
|
31 |
case 'compat-sgoptimize':
|
32 |
$this->buildNotice_CompatSgOptimize( $oNotice );
|
33 |
break;
|
@@ -36,10 +40,6 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
36 |
$this->buildNotice_PluginMailingListSignup( $oNotice );
|
37 |
break;
|
38 |
|
39 |
-
case 'plugin-update-available':
|
40 |
-
$this->buildNotice_UpdateAvailable( $oNotice );
|
41 |
-
break;
|
42 |
-
|
43 |
case 'wizard_welcome':
|
44 |
$this->buildNotice_WelcomeWizard( $oNotice );
|
45 |
break;
|
@@ -337,13 +337,12 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
337 |
$bNeeded = $oOpts->isPluginGloballyDisabled();
|
338 |
break;
|
339 |
|
340 |
-
case '
|
341 |
-
$bNeeded = (
|
342 |
break;
|
343 |
|
344 |
-
case '
|
345 |
-
$bNeeded =
|
346 |
-
&& Services::WpPlugins()->isUpdateAvailable( !Services::WpPost()->isPage_Updates() );
|
347 |
break;
|
348 |
|
349 |
case 'allow-tracking':
|
28 |
$this->buildNotice_PluginDisabled( $oNotice );
|
29 |
break;
|
30 |
|
31 |
+
case 'update-available':
|
32 |
+
$this->buildNotice_UpdateAvailable( $oNotice );
|
33 |
+
break;
|
34 |
+
|
35 |
case 'compat-sgoptimize':
|
36 |
$this->buildNotice_CompatSgOptimize( $oNotice );
|
37 |
break;
|
40 |
$this->buildNotice_PluginMailingListSignup( $oNotice );
|
41 |
break;
|
42 |
|
|
|
|
|
|
|
|
|
43 |
case 'wizard_welcome':
|
44 |
$this->buildNotice_WelcomeWizard( $oNotice );
|
45 |
break;
|
337 |
$bNeeded = $oOpts->isPluginGloballyDisabled();
|
338 |
break;
|
339 |
|
340 |
+
case 'update-available':
|
341 |
+
$bNeeded = Services::WpPlugins()->isUpdateAvailable( $oCon->getPluginBaseFile() );
|
342 |
break;
|
343 |
|
344 |
+
case 'compat-sgoptimize':
|
345 |
+
$bNeeded = ( new Plugin\Components\SiteGroundPluginCompatibility() )->testIsIncompatible();
|
|
|
346 |
break;
|
347 |
|
348 |
case 'allow-tracking':
|
src/lib/src/Modules/Plugin/AjaxHandler.php
CHANGED
@@ -10,11 +10,11 @@ use FernleafSystems\Wordpress\Services\Utilities\Net\FindSourceFromIp;
|
|
10 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
11 |
|
12 |
/**
|
13 |
-
* @param string $
|
14 |
* @return array
|
15 |
*/
|
16 |
-
protected function processAjaxAction( $
|
17 |
-
switch ( $
|
18 |
case 'bulk_action':
|
19 |
$aResponse = $this->ajaxExec_BulkItemAction();
|
20 |
break;
|
@@ -64,7 +64,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
64 |
break;
|
65 |
|
66 |
default:
|
67 |
-
$aResponse = parent::processAjaxAction( $
|
68 |
}
|
69 |
|
70 |
return $aResponse;
|
10 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
11 |
|
12 |
/**
|
13 |
+
* @param string $action
|
14 |
* @return array
|
15 |
*/
|
16 |
+
protected function processAjaxAction( $action ) {
|
17 |
+
switch ( $action ) {
|
18 |
case 'bulk_action':
|
19 |
$aResponse = $this->ajaxExec_BulkItemAction();
|
20 |
break;
|
64 |
break;
|
65 |
|
66 |
default:
|
67 |
+
$aResponse = parent::processAjaxAction( $action );
|
68 |
}
|
69 |
|
70 |
return $aResponse;
|
src/lib/src/Modules/Plugin/Lib/ImportExport/Export.php
CHANGED
@@ -121,9 +121,9 @@ class Export {
|
|
121 |
*/
|
122 |
private function getExportData() {
|
123 |
$aAll = [];
|
124 |
-
foreach ( $this->getCon()->modules as $
|
125 |
-
$oOpts = $
|
126 |
-
$aAll[ $
|
127 |
$oOpts->getTransferableOptions(),
|
128 |
array_flip( $oOpts->getXferExcluded() )
|
129 |
);
|
@@ -132,24 +132,24 @@ class Export {
|
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
-
* @param string $
|
136 |
* @return bool
|
137 |
*/
|
138 |
-
private function isUrlOnWhitelist( $
|
139 |
-
/** @var Plugin\Options $
|
140 |
-
$
|
141 |
-
return !empty( $
|
142 |
}
|
143 |
|
144 |
/**
|
145 |
-
* @param string $
|
146 |
* @return bool
|
147 |
*/
|
148 |
-
private function verifyUrlWithHandshake( $
|
149 |
$bVerified = false;
|
150 |
|
151 |
-
if ( !empty( $
|
152 |
-
$sReqUrl = add_query_arg( [ 'shield_action' => 'importexport_handshake' ], $
|
153 |
$aResp = @json_decode( Services::HttpRequest()->getContent( $sReqUrl ), true );
|
154 |
$bVerified = is_array( $aResp ) && isset( $aResp[ 'success' ] ) && ( $aResp[ 'success' ] === true );
|
155 |
}
|
121 |
*/
|
122 |
private function getExportData() {
|
123 |
$aAll = [];
|
124 |
+
foreach ( $this->getCon()->modules as $mod ) {
|
125 |
+
$oOpts = $mod->getOptions();
|
126 |
+
$aAll[ $mod->getOptionsStorageKey() ] = array_diff_key(
|
127 |
$oOpts->getTransferableOptions(),
|
128 |
array_flip( $oOpts->getXferExcluded() )
|
129 |
);
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
+
* @param string $url
|
136 |
* @return bool
|
137 |
*/
|
138 |
+
private function isUrlOnWhitelist( $url ) {
|
139 |
+
/** @var Plugin\Options $opts */
|
140 |
+
$opts = $this->getOptions();
|
141 |
+
return !empty( $url ) && in_array( $url, $opts->getImportExportWhitelist() );
|
142 |
}
|
143 |
|
144 |
/**
|
145 |
+
* @param string $url
|
146 |
* @return bool
|
147 |
*/
|
148 |
+
private function verifyUrlWithHandshake( $url ) {
|
149 |
$bVerified = false;
|
150 |
|
151 |
+
if ( !empty( $url ) ) {
|
152 |
+
$sReqUrl = add_query_arg( [ 'shield_action' => 'importexport_handshake' ], $url );
|
153 |
$aResp = @json_decode( Services::HttpRequest()->getContent( $sReqUrl ), true );
|
154 |
$bVerified = is_array( $aResp ) && isset( $aResp[ 'success' ] ) && ( $aResp[ 'success' ] === true );
|
155 |
}
|
src/lib/src/Modules/Plugin/Lib/ImportExport/Import.php
CHANGED
@@ -213,18 +213,18 @@ class Import {
|
|
213 |
$bImported = false;
|
214 |
|
215 |
$bAnythingChanged = false;
|
216 |
-
foreach ( $this->getCon()->modules as $
|
217 |
-
if ( !empty( $aImportData[ $
|
218 |
-
$oTheseOpts = $
|
219 |
$oTheseOpts->setMultipleOptions(
|
220 |
array_diff_key(
|
221 |
-
$aImportData[ $
|
222 |
array_flip( $oTheseOpts->getXferExcluded() )
|
223 |
)
|
224 |
);
|
225 |
|
226 |
$bAnythingChanged = $bAnythingChanged || $oTheseOpts->getNeedSave();
|
227 |
-
$
|
228 |
}
|
229 |
}
|
230 |
|
213 |
$bImported = false;
|
214 |
|
215 |
$bAnythingChanged = false;
|
216 |
+
foreach ( $this->getCon()->modules as $mod ) {
|
217 |
+
if ( !empty( $aImportData[ $mod->getOptionsStorageKey() ] ) ) {
|
218 |
+
$oTheseOpts = $mod->getOptions();
|
219 |
$oTheseOpts->setMultipleOptions(
|
220 |
array_diff_key(
|
221 |
+
$aImportData[ $mod->getOptionsStorageKey() ],
|
222 |
array_flip( $oTheseOpts->getXferExcluded() )
|
223 |
)
|
224 |
);
|
225 |
|
226 |
$bAnythingChanged = $bAnythingChanged || $oTheseOpts->getNeedSave();
|
227 |
+
$mod->saveModOptions( true );
|
228 |
}
|
229 |
}
|
230 |
|
src/lib/src/Modules/Plugin/Lib/Ops/ResetPlugin.php
CHANGED
@@ -13,11 +13,11 @@ class ResetPlugin {
|
|
13 |
use PluginControllerConsumer;
|
14 |
|
15 |
public function run() {
|
16 |
-
foreach ( $this->getCon()->modules as $
|
17 |
-
$
|
18 |
-
|
19 |
-
|
20 |
-
$
|
21 |
}
|
22 |
}
|
23 |
}
|
13 |
use PluginControllerConsumer;
|
14 |
|
15 |
public function run() {
|
16 |
+
foreach ( $this->getCon()->modules as $mod ) {
|
17 |
+
$mod->getOptions()
|
18 |
+
->setOptionsValues( [] )
|
19 |
+
->deleteStorage();
|
20 |
+
$mod->saveModOptions();
|
21 |
}
|
22 |
}
|
23 |
}
|
src/lib/src/Modules/Plugin/Options.php
CHANGED
@@ -23,6 +23,7 @@ class Options extends Base\ShieldOptions {
|
|
23 |
|
24 |
/**
|
25 |
* @return string[]
|
|
|
26 |
*/
|
27 |
public function getDbColumns_GeoIp() {
|
28 |
return $this->getDef( 'geoip_table_columns' );
|
@@ -30,6 +31,7 @@ class Options extends Base\ShieldOptions {
|
|
30 |
|
31 |
/**
|
32 |
* @return string[]
|
|
|
33 |
*/
|
34 |
public function getDbColumns_Notes() {
|
35 |
return $this->getDef( 'db_notes_table_columns' );
|
23 |
|
24 |
/**
|
25 |
* @return string[]
|
26 |
+
* @deprecated 9.2.0
|
27 |
*/
|
28 |
public function getDbColumns_GeoIp() {
|
29 |
return $this->getDef( 'geoip_table_columns' );
|
31 |
|
32 |
/**
|
33 |
* @return string[]
|
34 |
+
* @deprecated 9.2.0
|
35 |
*/
|
36 |
public function getDbColumns_Notes() {
|
37 |
return $this->getDef( 'db_notes_table_columns' );
|
src/lib/src/Modules/Plugin/Strings.php
CHANGED
@@ -51,14 +51,14 @@ class Strings extends Base\Strings {
|
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
-
* @param string $
|
55 |
* @return array
|
56 |
* @throws \Exception
|
57 |
*/
|
58 |
-
public function getSectionStrings( $
|
59 |
$sPlugName = $this->getCon()->getHumanName();
|
60 |
|
61 |
-
switch ( $
|
62 |
|
63 |
case 'section_global_security_options' :
|
64 |
$sTitle = __( 'Global Security Plugin Disable', 'wp-simple-firewall' );
|
@@ -113,7 +113,7 @@ class Strings extends Base\Strings {
|
|
113 |
break;
|
114 |
|
115 |
default:
|
116 |
-
return parent::getSectionStrings( $
|
117 |
}
|
118 |
|
119 |
return [
|
@@ -124,18 +124,18 @@ class Strings extends Base\Strings {
|
|
124 |
}
|
125 |
|
126 |
/**
|
127 |
-
* @param string $
|
128 |
* @return array
|
129 |
* @throws \Exception
|
130 |
*/
|
131 |
-
public function getOptionStrings( $
|
132 |
/** @var \ICWP_WPSF_FeatureHandler_Plugin $oMod */
|
133 |
$oMod = $this->getMod();
|
134 |
/** @var Options $oOpts */
|
135 |
$oOpts = $this->getOptions();
|
136 |
$sPlugName = $this->getCon()->getHumanName();
|
137 |
|
138 |
-
switch ( $
|
139 |
|
140 |
case 'global_enable_plugin_features' :
|
141 |
$sName = sprintf( __( 'Enable %s Protection', 'wp-simple-firewall' ), $sPlugName );
|
@@ -201,8 +201,8 @@ class Strings extends Base\Strings {
|
|
201 |
$sDescription = [
|
202 |
__( 'Enabling this option helps support the plugin by spreading the word about it on your website.', 'wp-simple-firewall' )
|
203 |
.' '.__( 'The plugin badge also lets visitors know your are taking your website security seriously.', 'wp-simple-firewall' ),
|
|
|
204 |
sprintf( '<strong><a href="%s" target="_blank">%s</a></strong>', 'https://shsec.io/wpsf20', __( 'Read this carefully before enabling this option.', 'wp-simple-firewall' ) ),
|
205 |
-
__( "This also acts as an affiliate link if you're running ShieldPRO so you can earn rewards for each referral.", 'wp-simple-firewall' ),
|
206 |
];
|
207 |
break;
|
208 |
|
@@ -227,24 +227,30 @@ class Strings extends Base\Strings {
|
|
227 |
case 'importexport_enable' :
|
228 |
$sName = __( 'Allow Import/Export', 'wp-simple-firewall' );
|
229 |
$sSummary = __( 'Allow Import And Export Of Options On This Site', 'wp-simple-firewall' );
|
230 |
-
$sDescription =
|
231 |
-
|
|
|
|
|
232 |
break;
|
233 |
|
234 |
case 'importexport_whitelist' :
|
235 |
$sName = __( 'Export Whitelist', 'wp-simple-firewall' );
|
236 |
$sSummary = __( 'Whitelisted Sites To Export Options From This Site', 'wp-simple-firewall' );
|
237 |
-
$sDescription =
|
238 |
-
|
239 |
-
|
|
|
|
|
240 |
break;
|
241 |
|
242 |
case 'importexport_masterurl' :
|
243 |
$sName = __( 'Master Import Site', 'wp-simple-firewall' );
|
244 |
$sSummary = __( 'Automatically Import Options From This Site URL', 'wp-simple-firewall' );
|
245 |
-
$sDescription =
|
246 |
-
|
247 |
-
|
|
|
|
|
248 |
break;
|
249 |
|
250 |
case 'importexport_whitelist_notify' :
|
@@ -281,15 +287,19 @@ class Strings extends Base\Strings {
|
|
281 |
case 'google_recaptcha_secret_key' :
|
282 |
$sName = __( 'CAPTCHA Secret', 'wp-simple-firewall' );
|
283 |
$sSummary = __( 'CAPTCHA Secret Key', 'wp-simple-firewall' );
|
284 |
-
$sDescription =
|
285 |
-
|
|
|
|
|
286 |
break;
|
287 |
|
288 |
case 'google_recaptcha_site_key' :
|
289 |
$sName = __( 'CAPTCHA Site Key', 'wp-simple-firewall' );
|
290 |
$sSummary = __( 'CAPTCHA Site Key', 'wp-simple-firewall' );
|
291 |
-
$sDescription =
|
292 |
-
|
|
|
|
|
293 |
break;
|
294 |
|
295 |
case 'google_recaptcha_style' :
|
@@ -299,7 +309,7 @@ class Strings extends Base\Strings {
|
|
299 |
break;
|
300 |
|
301 |
default:
|
302 |
-
return parent::getOptionStrings( $
|
303 |
}
|
304 |
|
305 |
return [
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
+
* @param string $section
|
55 |
* @return array
|
56 |
* @throws \Exception
|
57 |
*/
|
58 |
+
public function getSectionStrings( $section ) {
|
59 |
$sPlugName = $this->getCon()->getHumanName();
|
60 |
|
61 |
+
switch ( $section ) {
|
62 |
|
63 |
case 'section_global_security_options' :
|
64 |
$sTitle = __( 'Global Security Plugin Disable', 'wp-simple-firewall' );
|
113 |
break;
|
114 |
|
115 |
default:
|
116 |
+
return parent::getSectionStrings( $section );
|
117 |
}
|
118 |
|
119 |
return [
|
124 |
}
|
125 |
|
126 |
/**
|
127 |
+
* @param string $key
|
128 |
* @return array
|
129 |
* @throws \Exception
|
130 |
*/
|
131 |
+
public function getOptionStrings( $key ) {
|
132 |
/** @var \ICWP_WPSF_FeatureHandler_Plugin $oMod */
|
133 |
$oMod = $this->getMod();
|
134 |
/** @var Options $oOpts */
|
135 |
$oOpts = $this->getOptions();
|
136 |
$sPlugName = $this->getCon()->getHumanName();
|
137 |
|
138 |
+
switch ( $key ) {
|
139 |
|
140 |
case 'global_enable_plugin_features' :
|
141 |
$sName = sprintf( __( 'Enable %s Protection', 'wp-simple-firewall' ), $sPlugName );
|
201 |
$sDescription = [
|
202 |
__( 'Enabling this option helps support the plugin by spreading the word about it on your website.', 'wp-simple-firewall' )
|
203 |
.' '.__( 'The plugin badge also lets visitors know your are taking your website security seriously.', 'wp-simple-firewall' ),
|
204 |
+
__( "This also acts as an affiliate link if you're running ShieldPRO so you can earn rewards for each referral.", 'wp-simple-firewall' ),
|
205 |
sprintf( '<strong><a href="%s" target="_blank">%s</a></strong>', 'https://shsec.io/wpsf20', __( 'Read this carefully before enabling this option.', 'wp-simple-firewall' ) ),
|
|
|
206 |
];
|
207 |
break;
|
208 |
|
227 |
case 'importexport_enable' :
|
228 |
$sName = __( 'Allow Import/Export', 'wp-simple-firewall' );
|
229 |
$sSummary = __( 'Allow Import And Export Of Options On This Site', 'wp-simple-firewall' );
|
230 |
+
$sDescription = [
|
231 |
+
__( 'Uncheck this box to completely disable import and export of options.', 'wp-simple-firewall' ),
|
232 |
+
sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ), __( 'Import/Export is a premium-only feature.', 'wp-simple-firewall' ) )
|
233 |
+
];
|
234 |
break;
|
235 |
|
236 |
case 'importexport_whitelist' :
|
237 |
$sName = __( 'Export Whitelist', 'wp-simple-firewall' );
|
238 |
$sSummary = __( 'Whitelisted Sites To Export Options From This Site', 'wp-simple-firewall' );
|
239 |
+
$sDescription = [
|
240 |
+
__( 'Whitelisted sites may export options from this site without the key.', 'wp-simple-firewall' ),
|
241 |
+
__( 'List each site URL on a new line.', 'wp-simple-firewall' ),
|
242 |
+
__( 'This is to be used in conjunction with the Master Import Site feature.', 'wp-simple-firewall' )
|
243 |
+
];
|
244 |
break;
|
245 |
|
246 |
case 'importexport_masterurl' :
|
247 |
$sName = __( 'Master Import Site', 'wp-simple-firewall' );
|
248 |
$sSummary = __( 'Automatically Import Options From This Site URL', 'wp-simple-firewall' );
|
249 |
+
$sDescription = [
|
250 |
+
__( "Supplying a site URL here will make this site an 'Options Slave'.", 'wp-simple-firewall' ),
|
251 |
+
__( 'Options will be automatically exported from the Master site each day.', 'wp-simple-firewall' ),
|
252 |
+
sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ), __( 'Use of this feature will overwrite existing options and replace them with those from the Master Import Site.', 'wp-simple-firewall' ) )
|
253 |
+
];
|
254 |
break;
|
255 |
|
256 |
case 'importexport_whitelist_notify' :
|
287 |
case 'google_recaptcha_secret_key' :
|
288 |
$sName = __( 'CAPTCHA Secret', 'wp-simple-firewall' );
|
289 |
$sSummary = __( 'CAPTCHA Secret Key', 'wp-simple-firewall' );
|
290 |
+
$sDescription = [
|
291 |
+
__( 'Enter your CAPTCHA secret key for use throughout the plugin.', 'wp-simple-firewall' ),
|
292 |
+
sprintf( '<strong>%s</strong>: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Google reCAPTCHA v3 not supported.', 'wp-simple-firewall' ) )
|
293 |
+
];
|
294 |
break;
|
295 |
|
296 |
case 'google_recaptcha_site_key' :
|
297 |
$sName = __( 'CAPTCHA Site Key', 'wp-simple-firewall' );
|
298 |
$sSummary = __( 'CAPTCHA Site Key', 'wp-simple-firewall' );
|
299 |
+
$sDescription = [
|
300 |
+
__( 'Enter your CAPTCHA site key for use throughout the plugin.', 'wp-simple-firewall' ),
|
301 |
+
sprintf( '<strong>%s</strong>: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Google reCAPTCHA v3 not supported.', 'wp-simple-firewall' ) )
|
302 |
+
];
|
303 |
break;
|
304 |
|
305 |
case 'google_recaptcha_style' :
|
309 |
break;
|
310 |
|
311 |
default:
|
312 |
+
return parent::getOptionStrings( $key );
|
313 |
}
|
314 |
|
315 |
return [
|
src/lib/src/Modules/Plugin/UI.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\Captcha\CheckCaptchaSettings;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class UI extends Base\ShieldUI {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array $aOptParams
|
13 |
+
* @return array
|
14 |
+
*/
|
15 |
+
protected function buildOptionForUi( $aOptParams ) {
|
16 |
+
$aOptParams = parent::buildOptionForUi( $aOptParams );
|
17 |
+
if ( $aOptParams[ 'key' ] === 'visitor_address_source' ) {
|
18 |
+
$aNewOptions = [];
|
19 |
+
$oIPDet = Services::IP()->getIpDetector();
|
20 |
+
foreach ( $aOptParams[ 'value_options' ] as $sValKey => $sSource ) {
|
21 |
+
if ( $sValKey == 'AUTO_DETECT_IP' ) {
|
22 |
+
$aNewOptions[ $sValKey ] = $sSource;
|
23 |
+
}
|
24 |
+
else {
|
25 |
+
$sIPs = implode( ', ', $oIPDet->getIpsFromSource( $sSource ) );
|
26 |
+
$aNewOptions[ $sValKey ] = sprintf( '%s (%s)',
|
27 |
+
$sSource, empty( $sIPs ) ? '-' : $sIPs );
|
28 |
+
}
|
29 |
+
}
|
30 |
+
$aOptParams[ 'value_options' ] = $aNewOptions;
|
31 |
+
}
|
32 |
+
return $aOptParams;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
public function getInsightsConfigCardData() {
|
39 |
+
/** @var \ICWP_WPSF_FeatureHandler_Plugin $mod */
|
40 |
+
$mod = $this->getMod();
|
41 |
+
/** @var Options $opts */
|
42 |
+
$opts = $this->getOptions();
|
43 |
+
$data = [
|
44 |
+
'strings' => [
|
45 |
+
'title' => __( 'General Settings', 'wp-simple-firewall' ),
|
46 |
+
'sub' => sprintf( __( 'General %s Settings', 'wp-simple-firewall' ), $this->getCon()
|
47 |
+
->getHumanName() ),
|
48 |
+
],
|
49 |
+
'key_opts' => [],
|
50 |
+
'href_options' => $mod->getUrl_AdminPage()
|
51 |
+
];
|
52 |
+
|
53 |
+
if ( $mod->isModOptEnabled() ) {
|
54 |
+
$data[ 'key_opts' ][ 'mod' ] = $this->getModDisabledInsight();
|
55 |
+
}
|
56 |
+
else {
|
57 |
+
$data[ 'key_opts' ][ 'editing' ] = [
|
58 |
+
'name' => __( 'Visitor IP', 'wp-simple-firewall' ),
|
59 |
+
'enabled' => true,
|
60 |
+
'summary' => sprintf( __( 'Visitor IP address source is: %s', 'wp-simple-firewall' ),
|
61 |
+
__( $opts->getSelectOptionValueText( 'visitor_address_source' ), 'wp-simple-firewall' ) ),
|
62 |
+
'weight' => 0,
|
63 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'visitor_address_source' ),
|
64 |
+
];
|
65 |
+
|
66 |
+
$bHasSupportEmail = Services::Data()->validEmail( $opts->getOpt( 'block_send_email_address' ) );
|
67 |
+
$data[ 'key_opts' ][ 'reports' ] = [
|
68 |
+
'name' => __( 'Reporting Email', 'wp-simple-firewall' ),
|
69 |
+
'enabled' => $bHasSupportEmail,
|
70 |
+
'summary' => $bHasSupportEmail ?
|
71 |
+
sprintf( __( 'Email address for reports set to: %s', 'wp-simple-firewall' ), $mod->getPluginReportEmail() )
|
72 |
+
: sprintf( __( 'No address provided - defaulting to: %s', 'wp-simple-firewall' ), $mod->getPluginReportEmail() ),
|
73 |
+
'weight' => 0,
|
74 |
+
'href' => $mod->getUrl_DirectLinkToOption( 'block_send_email_address' ),
|
75 |
+
];
|
76 |
+
|
77 |
+
$bRecap = $mod->getCaptchaCfg()->ready;
|
78 |
+
$data[ 'key_opts' ][ 'recap' ] = [
|
79 |
+
'name' => __( 'CAPTCHA', 'wp-simple-firewall' ),
|
80 |
+
'enabled' => $bRecap,
|
81 |
+
'summary' => $bRecap ?
|
82 |
+
__( 'CAPTCHA keys have been provided', 'wp-simple-firewall' )
|
83 |
+
: __( "CAPTCHA keys haven't been provided", 'wp-simple-firewall' ),
|
84 |
+
'weight' => 1,
|
85 |
+
'href' => $mod->getUrl_DirectLinkToSection( 'section_third_party_captcha' ),
|
86 |
+
];
|
87 |
+
}
|
88 |
+
|
89 |
+
return $data;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @param string $section
|
94 |
+
* @return array
|
95 |
+
*/
|
96 |
+
protected function getSectionWarnings( $section ) {
|
97 |
+
/** @var \ICWP_WPSF_FeatureHandler_Plugin $mod */
|
98 |
+
$mod = $this->getMod();
|
99 |
+
$opts = $this->getOptions();
|
100 |
+
$aWarnings = [];
|
101 |
+
|
102 |
+
switch ( $section ) {
|
103 |
+
case 'section_third_party_captcha':
|
104 |
+
if ( $mod->getCaptchaCfg()->ready ) {
|
105 |
+
if ( $opts->getOpt( 'captcha_checked_at' ) < 0 ) {
|
106 |
+
( new CheckCaptchaSettings() )
|
107 |
+
->setMod( $mod )
|
108 |
+
->checkAll();
|
109 |
+
}
|
110 |
+
if ( $opts->getOpt( 'captcha_checked_at' ) == 0 ) {
|
111 |
+
$aWarnings[] = sprintf(
|
112 |
+
__( "Your captcha key and secret haven't been verified.", 'wp-simple-firewall' ).' '
|
113 |
+
.__( "Please double-check and make sure you haven't mixed them about, and then re-save.", 'wp-simple-firewall' )
|
114 |
+
);
|
115 |
+
}
|
116 |
+
}
|
117 |
+
break;
|
118 |
+
}
|
119 |
+
|
120 |
+
return $aWarnings;
|
121 |
+
}
|
122 |
+
}
|
src/lib/src/Modules/Reporting/Options.php
CHANGED
@@ -8,6 +8,7 @@ class Options extends Base\ShieldOptions {
|
|
8 |
|
9 |
/**
|
10 |
* @return string[]
|
|
|
11 |
*/
|
12 |
public function getDbColumns_Reports() {
|
13 |
return $this->getDef( 'reports_table_columns' );
|
8 |
|
9 |
/**
|
10 |
* @return string[]
|
11 |
+
* @deprecated 9.2.0
|
12 |
*/
|
13 |
public function getDbColumns_Reports() {
|
14 |
return $this->getDef( 'reports_table_columns' );
|
src/lib/src/Modules/Reporting/Strings.php
CHANGED
@@ -54,14 +54,14 @@ class Strings extends Base\Strings {
|
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
-
* @param string $
|
58 |
* @return array
|
59 |
* @throws \Exception
|
60 |
*/
|
61 |
-
public function getOptionStrings( $
|
62 |
$oCon = $this->getCon();
|
63 |
|
64 |
-
switch ( $
|
65 |
|
66 |
case 'frequency_alert' :
|
67 |
$sName = __( 'Alert Frequency', 'wp-simple-firewall' );
|
@@ -90,7 +90,7 @@ class Strings extends Base\Strings {
|
|
90 |
break;
|
91 |
|
92 |
default:
|
93 |
-
return parent::getOptionStrings( $
|
94 |
}
|
95 |
|
96 |
return [
|
@@ -101,13 +101,13 @@ class Strings extends Base\Strings {
|
|
101 |
}
|
102 |
|
103 |
/**
|
104 |
-
* @param string $
|
105 |
* @return array
|
106 |
* @throws \Exception
|
107 |
*/
|
108 |
-
public function getSectionStrings( $
|
109 |
|
110 |
-
switch ( $
|
111 |
|
112 |
case 'section_timings' :
|
113 |
$sTitle = __( 'Report Frequencies', 'wp-simple-firewall' );
|
@@ -126,7 +126,7 @@ class Strings extends Base\Strings {
|
|
126 |
break;
|
127 |
|
128 |
default:
|
129 |
-
return parent::getSectionStrings( $
|
130 |
}
|
131 |
|
132 |
return [
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
+
* @param string $key
|
58 |
* @return array
|
59 |
* @throws \Exception
|
60 |
*/
|
61 |
+
public function getOptionStrings( $key ) {
|
62 |
$oCon = $this->getCon();
|
63 |
|
64 |
+
switch ( $key ) {
|
65 |
|
66 |
case 'frequency_alert' :
|
67 |
$sName = __( 'Alert Frequency', 'wp-simple-firewall' );
|
90 |
break;
|
91 |
|
92 |
default:
|
93 |
+
return parent::getOptionStrings( $key );
|
94 |
}
|
95 |
|
96 |
return [
|
101 |
}
|
102 |
|
103 |
/**
|
104 |
+
* @param string $section
|
105 |
* @return array
|
106 |
* @throws \Exception
|
107 |
*/
|
108 |
+
public function getSectionStrings( $section ) {
|
109 |
|
110 |
+
switch ( $section ) {
|
111 |
|
112 |
case 'section_timings' :
|
113 |
$sTitle = __( 'Report Frequencies', 'wp-simple-firewall' );
|
126 |
break;
|
127 |
|
128 |
default:
|
129 |
+
return parent::getSectionStrings( $section );
|
130 |
}
|
131 |
|
132 |
return [
|
src/lib/src/Modules/SecurityAdmin/AdminNotices.php
CHANGED
@@ -90,10 +90,8 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
90 |
* @return bool
|
91 |
*/
|
92 |
protected function isDisplayNeeded( $oNotice ) {
|
93 |
-
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
94 |
-
$oMod = $this->getMod();
|
95 |
/** @var Options $oOpts */
|
96 |
-
$oOpts = $
|
97 |
|
98 |
$sCurrentPage = Services::WpPost()->getCurrentPage();
|
99 |
|
90 |
* @return bool
|
91 |
*/
|
92 |
protected function isDisplayNeeded( $oNotice ) {
|
|
|
|
|
93 |
/** @var Options $oOpts */
|
94 |
+
$oOpts = $this->getOptions();
|
95 |
|
96 |
$sCurrentPage = Services::WpPost()->getCurrentPage();
|
97 |
|
src/lib/src/Modules/SecurityAdmin/AjaxHandler.php
CHANGED
@@ -8,12 +8,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
-
* @param string $
|
12 |
* @return array
|
13 |
*/
|
14 |
-
protected function processAjaxAction( $
|
15 |
|
16 |
-
switch ( $
|
17 |
case 'sec_admin_check':
|
18 |
$aResponse = $this->ajaxExec_SecAdminCheck();
|
19 |
break;
|
@@ -32,7 +32,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
32 |
break;
|
33 |
|
34 |
default:
|
35 |
-
$aResponse = parent::processAjaxAction( $
|
36 |
}
|
37 |
|
38 |
return $aResponse;
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
|
10 |
/**
|
11 |
+
* @param string $action
|
12 |
* @return array
|
13 |
*/
|
14 |
+
protected function processAjaxAction( $action ) {
|
15 |
|
16 |
+
switch ( $action ) {
|
17 |
case 'sec_admin_check':
|
18 |
$aResponse = $this->ajaxExec_SecAdminCheck();
|
19 |
break;
|
32 |
break;
|
33 |
|
34 |
default:
|
35 |
+
$aResponse = parent::processAjaxAction( $action );
|
36 |
}
|
37 |
|
38 |
return $aResponse;
|
src/lib/src/Modules/SecurityAdmin/Lib/Actions/RemoveSecAdmin.php
CHANGED
@@ -11,10 +11,10 @@ class RemoveSecAdmin {
|
|
11 |
use ModConsumer;
|
12 |
|
13 |
public function remove() {
|
14 |
-
/** @var SecurityAdmin\Options $
|
15 |
-
$
|
16 |
-
if ( $
|
17 |
-
$
|
18 |
$this->getMod()->saveModOptions();
|
19 |
$this->sendNotificationEmail();
|
20 |
}
|
11 |
use ModConsumer;
|
12 |
|
13 |
public function remove() {
|
14 |
+
/** @var SecurityAdmin\Options $opts */
|
15 |
+
$opts = $this->getOptions();
|
16 |
+
if ( $opts->hasSecurityPIN() ) {
|
17 |
+
$opts->clearSecurityAdminKey();
|
18 |
$this->getMod()->saveModOptions();
|
19 |
$this->sendNotificationEmail();
|
20 |
}
|
src/lib/src/Modules/SecurityAdmin/Lib/WhiteLabel/ApplyLabels.php
CHANGED
@@ -10,8 +10,6 @@ class ApplyLabels {
|
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
13 |
-
/**
|
14 |
-
*/
|
15 |
public function run() {
|
16 |
$oCon = $this->getCon();
|
17 |
add_action( 'init', [ $this, 'onWpInit' ] );
|
10 |
|
11 |
use ModConsumer;
|
12 |
|
|
|
|
|
13 |
public function run() {
|
14 |
$oCon = $this->getCon();
|
15 |
add_action( 'init', [ $this, 'onWpInit' ] );
|
src/lib/src/Modules/SecurityAdmin/Options.php
CHANGED
@@ -61,31 +61,31 @@ class Options extends Base\ShieldOptions {
|
|
61 |
|
62 |
/**
|
63 |
* TODO: Bug where if $sType is defined, it'll be set to 'wp' anyway
|
64 |
-
* @param string $
|
65 |
* @return array
|
66 |
*/
|
67 |
-
public function getOptionsToRestrict( $
|
68 |
-
$
|
69 |
$aOptions = $this->getRestrictedOptions();
|
70 |
-
return ( isset( $aOptions[ $
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
-
* @param string $
|
75 |
* @return array
|
76 |
*/
|
77 |
-
public function getOptionsPagesToRestrict( $
|
78 |
-
$
|
79 |
$aOptions = $this->getRestrictedOptions();
|
80 |
-
return ( isset( $aOptions[ $
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
* @return array
|
85 |
*/
|
86 |
public function getSecurityAdminUsers() {
|
87 |
-
$
|
88 |
-
return ( is_array( $
|
89 |
}
|
90 |
|
91 |
/**
|
@@ -132,18 +132,17 @@ class Options extends Base\ShieldOptions {
|
|
132 |
|
133 |
/**
|
134 |
* @return bool
|
135 |
-
*
|
61 |
|
62 |
/**
|
63 |
* TODO: Bug where if $sType is defined, it'll be set to 'wp' anyway
|
64 |
+
* @param string $type - wp or wpms
|
65 |
* @return array
|
66 |
*/
|
67 |
+
public function getOptionsToRestrict( $type = '' ) {
|
68 |
+
$type = empty( $type ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
|
69 |
$aOptions = $this->getRestrictedOptions();
|
70 |
+
return ( isset( $aOptions[ $type.'_options' ] ) && is_array( $aOptions[ $type.'_options' ] ) ) ? $aOptions[ $type.'_options' ] : [];
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* @param string $type - wp or wpms
|
75 |
* @return array
|
76 |
*/
|
77 |
+
public function getOptionsPagesToRestrict( $type = '' ) {
|
78 |
+
$type = empty( $type ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
|
79 |
$aOptions = $this->getRestrictedOptions();
|
80 |
+
return ( isset( $aOptions[ $type.'_pages' ] ) && is_array( $aOptions[ $type.'_pages' ] ) ) ? $aOptions[ $type.'_pages' ] : [];
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
* @return array
|
85 |
*/
|
86 |
public function getSecurityAdminUsers() {
|
87 |
+
$users = $this->getOpt( 'sec_admin_users', [] );
|
88 |
+
return ( is_array( $users ) && $this->isPremium() ) ? $users : [];
|
89 |
}
|
90 |
|
91 |
/**
|
132 |
|
133 |
/**
|
134 |
* @return bool
|
|