diff --git a/.all-contributorsrc b/.all-contributorsrc
index ce485028d8..21a93ff2c9 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -7145,6 +7145,34 @@
"bug",
"code"
]
+ },
+ {
+ "login": "nwcm",
+ "name": "nwcm",
+ "avatar_url": "https://avatars.githubusercontent.com/u/111259588?v=4",
+ "profile": "https://github.com/nwcm",
+ "contributions": [
+ "doc"
+ ]
+ },
+ {
+ "login": "PimvanderLoos",
+ "name": "Pim van der Loos",
+ "avatar_url": "https://avatars.githubusercontent.com/u/3114723?v=4",
+ "profile": "https://github.com/PimvanderLoos",
+ "contributions": [
+ "code",
+ "test"
+ ]
+ },
+ {
+ "login": "joaodinissf",
+ "name": "João Dinis Ferreira",
+ "avatar_url": "https://avatars.githubusercontent.com/u/6786818?v=4",
+ "profile": "https://github.com/joaodinissf",
+ "contributions": [
+ "doc"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/.ci/README.md b/.ci/README.md
index 87250d6ba7..6286fd14b4 100644
--- a/.ci/README.md
+++ b/.ci/README.md
@@ -138,7 +138,7 @@ f=check-environment.sh; \
Calling `.ci/build.sh` directly would re-release the tag $TAG_NAME - that's why it is commented out.
All the side-effects of a release would be carried out like creating and publishing a release on github,
-uploading the release to sourceforge, uploading the docs to pmd.github.io/docs.pmd-code.org, uploading a
+uploading the release to sourceforge, uploading the docs to docs.pmd-code.org, uploading a
new baseline for the regression tester and so on. While the release should be reproducible and therefore should
produce exactly the same artifacts, re-uploading artifacts is not desired just for testing.
diff --git a/.ci/build.sh b/.ci/build.sh
index 5f4d321698..ac5986007b 100755
--- a/.ci/build.sh
+++ b/.ci/build.sh
@@ -55,6 +55,13 @@ function build() {
# stop early for invalid maven version and branch/tag combination
pmd_ci_maven_verify_version || exit 0
+ # skip tests when doing a release build - this makes the process faster
+ # it's a manual task now to verify that a release is only started, when the main branch
+ # was green before. This is usually checked via a local build, see ./do-release.sh
+ if pmd_ci_maven_isReleaseBuild; then
+ PMD_MAVEN_EXTRA_OPTS+=(-DskipTests=true)
+ fi
+
if [ "$(pmd_ci_utils_get_os)" != "linux" ]; then
pmd_ci_log_group_start "Build with mvnw"
./mvnw clean verify --show-version --errors --batch-mode --no-transfer-progress "${PMD_MAVEN_EXTRA_OPTS[@]}"
@@ -179,6 +186,11 @@ function pmd_ci_deploy_build_artifacts() {
# Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/
pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-bin-${PMD_CI_MAVEN_PROJECT_VERSION}.zip"
pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-src-${PMD_CI_MAVEN_PROJECT_VERSION}.zip"
+ # Deploy SBOM
+ cp pmd-dist/target/bom.xml "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml"
+ cp pmd-dist/target/bom.json "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json"
+ pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml"
+ pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json"
if pmd_ci_maven_isReleaseBuild; then
# create a draft github release
@@ -188,6 +200,9 @@ function pmd_ci_deploy_build_artifacts() {
# Deploy to github releases
pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-bin-${PMD_CI_MAVEN_PROJECT_VERSION}.zip"
pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-src-${PMD_CI_MAVEN_PROJECT_VERSION}.zip"
+ # Deploy SBOM
+ pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml"
+ pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json"
fi
}
@@ -224,7 +239,7 @@ function pmd_ci_build_and_upload_doc() {
pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}"
if pmd_ci_maven_isSnapshotBuild && [ "${PMD_CI_BRANCH}" = "master" ]; then
- # only for snapshot builds from branch master
+ # only for snapshot builds from branch master: https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}
pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "snapshot"
# update github pages https://pmd.github.io/pmd/
@@ -249,14 +264,12 @@ function pmd_ci_build_and_upload_doc() {
local rendered_release_notes_with_links
rendered_release_notes_with_links="
* Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_CI_MAVEN_PROJECT_VERSION}
-* Documentation: https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/
+* Documentation: https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/
${rendered_release_notes}"
pmd_ci_sourceforge_createDraftBlogPost "${release_name} released" "${rendered_release_notes_with_links}" "pmd,release"
SF_BLOG_URL="${RESULT}"
- # updates https://pmd.github.io/latest/ and https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}
- publish_release_documentation_github
# rsync site to https://pmd.sourceforge.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}
pmd_ci_sourceforge_rsyncSnapshotDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
fi
diff --git a/.ci/inc/pmd-doc.inc b/.ci/inc/pmd-doc.inc
index 4a6d5acc14..8969f8a4d8 100644
--- a/.ci/inc/pmd-doc.inc
+++ b/.ci/inc/pmd-doc.inc
@@ -42,55 +42,7 @@ function pmd_doc_create_archive() {
}
#
-# Publishes the site to https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION} and
-# https://pmd.github.io/latest/
-#
-function publish_release_documentation_github() {
- echo -e "\n\n"
- pmd_ci_log_info "Adding the new doc to pmd.github.io..."
- # clone pmd.github.io. Note: This uses the ssh key setup earlier
- # In order to speed things up, we use a sparse checkout - no need to checkout all directories here
- mkdir pmd.github.io
- (
- cd pmd.github.io || { echo "Directory 'pmd.github.io' doesn't exist"; exit 1; }
- git init
- git config user.name "PMD CI (pmd-bot)"
- git config user.email "pmd-bot@users.noreply.github.com"
- git config core.sparsecheckout true
- git remote add origin git@github.com-pmd.github.io:pmd/pmd.github.io.git
- echo "/latest/" > .git/info/sparse-checkout
- echo "/sitemap.xml" >> .git/info/sparse-checkout
- git pull --depth=1 origin master
- pmd_ci_log_info "Copying documentation from ../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ to pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/ ..."
- rsync -ah --stats "../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/"
- git status
- pmd_ci_log_debug "Executing: git add pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
- git add --sparse "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
- pmd_ci_log_debug "Executing: git commit..."
- git commit -q -m "Added pmd-${PMD_CI_MAVEN_PROJECT_VERSION}"
-
- pmd_ci_log_info "Copying pmd-${PMD_CI_MAVEN_PROJECT_VERSION} to latest ..."
- git rm -qr latest
- cp -a "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" latest
- pmd_ci_log_debug "Executing: git add latest"
- git add latest
- pmd_ci_log_debug "Executing: git commit..."
- git commit -q -m "Copying pmd-${PMD_CI_MAVEN_PROJECT_VERSION} to latest"
-
- pmd_ci_log_info "Generating sitemap.xml"
- ../docs/sitemap_generator.sh > sitemap.xml
- pmd_ci_log_debug "Executing: git add sitemap.xml"
- git add sitemap.xml
- pmd_ci_log_debug "Executing: git commit..."
- git commit -q -m "Generated sitemap.xml"
-
- pmd_ci_log_info "Executing: git push origin master"
- git push origin master
- )
-}
-
-#
-# Updates github pages of the main repository,
+# Updates github pages branch "gh-pages" of the main repository,
# so that https://pmd.github.io/pmd/ has the latest (snapshot) content
#
function pmd_doc_publish_to_github_pages() {
diff --git a/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md b/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md
index 8faed7c14a..9daab4f380 100644
--- a/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md
+++ b/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md
@@ -13,7 +13,7 @@ assignees: ''
**Rule:**
Please provide the rule name and a link to the rule documentation:
-
+
**Description:**
diff --git a/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md b/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md
index 51702e0038..d6ae5c5d0d 100644
--- a/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md
+++ b/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md
@@ -13,7 +13,7 @@ assignees: ''
**Rule:**
Please provide the rule name and a link to the rule documentation:
-
+
**Description:**
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ed97a2878b..b4fe5f9d27 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -33,11 +33,11 @@ When filing a bug report, please provide as much information as possible, so tha
## Documentation
-There is some documentation available under . Feel free to create a bug report if
+There is some documentation available under . Feel free to create a bug report if
documentation is missing, incomplete or outdated. See [Bug reports](#bug-reports).
The documentation is generated as a Jekyll site, the source is available at: . You can find build instructions there.
-For more on contributing documentation check
+For more on contributing documentation check
## Questions
diff --git a/Gemfile.lock b/Gemfile.lock
index aa09f3659b..d96519a4e1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
- addressable (2.8.1)
+ addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
claide (1.1.0)
claide-plugins (0.9.2)
@@ -31,13 +31,13 @@ GEM
faraday (2.7.4)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
- faraday-http-cache (2.4.1)
+ faraday-http-cache (2.5.0)
faraday (>= 0.8)
faraday-net_http (3.0.2)
fugit (1.8.1)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
- git (1.17.2)
+ git (1.18.0)
addressable (~> 2.8)
rchardet (~> 1.8)
kramdown (2.4.0)
@@ -49,7 +49,7 @@ GEM
mini_portile2 (2.8.1)
nap (1.1.0)
no_proxy_fix (0.1.2)
- nokogiri (1.14.2)
+ nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (5.6.1)
diff --git a/README.md b/README.md
index 5fe24a5db5..382eb8ca61 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[](https://coveralls.io/github/pmd/pmd)
[](https://www.codacy.com/gh/pmd/pmd/dashboard?utm_source=github.com&utm_medium=referral&utm_content=pmd/pmd&utm_campaign=Badge_Grade)
[](code_of_conduct.md)
-[](https://pmd.github.io/latest/)
+[](https://docs.pmd-code.org/latest/)
**PMD** is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
unnecessary object creation, and so forth. It supports many languages. It can be extended with custom rules.
@@ -32,9 +32,9 @@ it makes sense.
Download the latest binary zip from the [releases](https://github.com/pmd/pmd/releases/latest)
and extract it somewhere.
-Execute `bin/run.sh pmd` or `bin\pmd.bat`.
+Execute `bin/pmd check` or `bin\pmd.bat check`.
-See also [Getting Started](https://pmd.github.io/latest/pmd_userdocs_installation.html)
+See also [Getting Started](https://docs.pmd-code.org/latest/pmd_userdocs_installation.html)
**Demo:**
@@ -43,7 +43,7 @@ This shows how PMD can detect for loops, that can be replaced by for-each loops.

There are plugins for Maven and Gradle as well as for various IDEs.
-See [Tools / Integrations](https://pmd.github.io/latest/pmd_userdocs_tools.html)
+See [Tools / Integrations](https://docs.pmd-code.org/latest/pmd_userdocs_tools.html)
## ℹ️ How to get support?
@@ -54,7 +54,7 @@ See [Tools / Integrations](https://pmd.github.io/latest/pmd_userdocs_tools.html)
* I got this error and I'm sure it's a bug -- file an [issue](https://github.com/pmd/pmd/issues).
* I have an idea/request/question -- create a new [discussion](https://github.com/pmd/pmd/discussions).
* I have a quick question -- ask in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im).
-* Where's your documentation? --
+* Where's your documentation? --
## 🤝 Contributing
diff --git a/do-release.sh b/do-release.sh
index 7a42d9be4e..60d060c944 100755
--- a/do-release.sh
+++ b/do-release.sh
@@ -165,26 +165,13 @@ git commit -a -m "Prepare pmd release ${RELEASE_VERSION}"
fi
)
-# for release candidates, allow snapshot dependencies
-if [[ "${RELEASE_VERSION}" == *-rc* ]]; then
- ./mvnw versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false
- git commit -S -a -m "[release] prepare release pmd_releases/${RELEASE_VERSION}"
- git tag -a -s -m "[release] tag pmd_releases/${RELEASE_VERSION}" "pmd_releases/${RELEASE_VERSION}"
- # test build
- ./mvnw clean verify -Denforcer.skip=true
- ./mvnw versions:set -DnewVersion="${DEVELOPMENT_VERSION}" -DgenerateBackupPoms=false
- git commit -S -a -m "[release] prepare for next development iteration"
- # push
- git push origin
- git push origin tag "pmd_releases/${RELEASE_VERSION}"
-else
- ./mvnw -B release:clean release:prepare \
- -Dtag="pmd_releases/${RELEASE_VERSION}" \
- -DreleaseVersion="${RELEASE_VERSION}" \
- -DdevelopmentVersion="${DEVELOPMENT_VERSION}" \
- -DscmCommentPrefix="[release] " \
- -Pgenerate-rule-docs
-fi
+./mvnw -B release:clean release:prepare \
+ -Dtag="pmd_releases/${RELEASE_VERSION}" \
+ -DreleaseVersion="${RELEASE_VERSION}" \
+ -DdevelopmentVersion="${DEVELOPMENT_VERSION}" \
+ -DscmCommentPrefix="[release] " \
+ -Pgenerate-rule-docs
+
echo
echo "Tag has been pushed.... now check github actions: "
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
index 0a0f1cccb1..661669d561 100644
--- a/docs/Gemfile.lock
+++ b/docs/Gemfile.lock
@@ -6,17 +6,17 @@ GEM
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
- addressable (2.8.1)
+ addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
- commonmarker (0.23.8)
+ commonmarker (0.23.9)
concurrent-ruby (1.2.2)
- dnsruby (1.61.9)
- simpleidn (~> 0.1)
+ dnsruby (1.70.0)
+ simpleidn (~> 0.2.1)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
@@ -86,7 +86,7 @@ GEM
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.8.0)
- i18n (1.12.0)
+ i18n (1.13.0)
concurrent-ruby (~> 1.0)
jekyll (3.9.3)
addressable (~> 2.4)
@@ -211,7 +211,7 @@ GEM
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.18.0)
- nokogiri (1.14.2)
+ nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (4.25.1)
diff --git a/docs/README.md b/docs/README.md
index d0aef2914f..71c8eaf911 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,8 +1,10 @@
# PMD Documentation
-The documentation is available at:
+The snapshot documentation (build by github pages) is available at: .
-The documentation for the latest release is at:
+The same documentation (build with our own scripts) is available at: .
+
+The documentation for the latest release is at:
## Site Theme
diff --git a/docs/_config.yml b/docs/_config.yml
index 920e5d9a1c..4dc5eee07d 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -44,7 +44,6 @@ exclude:
- pdf-*.sh
- pdfconfigs/
- pdf/
- - sitemap_generator.sh
- render_release_notes.rb
feedback_subject_line: PMD Source Code Analyzer
@@ -117,7 +116,7 @@ description: "Intended as a documentation theme based on Jekyll for technical wr
# the description is used in the feed.xml file
# needed for sitemap.xml file only
-url: https://pmd.github.io/pmd
+url: https://docs.pmd-code.org/latest
baseurl: ""
# used by javadoc_tag.rb
diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml
index 6ca086dc8f..cb0a560ccb 100644
--- a/docs/_data/sidebars/pmd_sidebar.yml
+++ b/docs/_data/sidebars/pmd_sidebar.yml
@@ -409,6 +409,9 @@ entries:
- title: Java
url: /pmd_languages_java.html
output: web, pdf
+ - title: JavaScript / TypeScript
+ url: /pmd_languages_js_ts.html
+ output: web, pdf
- title: JSP
url: /pmd_languages_jsp.html
output: web, pdf
@@ -430,6 +433,9 @@ entries:
- title: Gherkin
url: /pmd_languages_gherkin.html
output: web, pdf
+ - title: Julia
+ url: /pmd_languages_julia.html
+ output: web, pdf
- title: Developer Documentation
output: web, pdf
folderitems:
@@ -469,7 +475,7 @@ entries:
- title: Adding a new language (JavaCC)
url: /pmd_devdocs_major_adding_new_language_javacc.html
output: web, pdf
- - title: Adding a new language (Antlr)
+ - title: Adding a new language (ANTLR)
url: /pmd_devdocs_major_adding_new_language_antlr.html
output: web, pdf
- title: Adding a new CPD language
diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html
index e8e3c871f4..46187408cf 100755
--- a/docs/_includes/footer.html
+++ b/docs/_includes/footer.html
@@ -9,7 +9,7 @@
target="_blank"
href="https://github.com/{{site.github_editme_path}}{{editmepath}}"
role="button"
- > Edit on GitHub Edit on GitHub
{% endif %}
diff --git a/docs/_includes/head.html b/docs/_includes/head.html
index 806206b577..a81e15c796 100644
--- a/docs/_includes/head.html
+++ b/docs/_includes/head.html
@@ -6,7 +6,7 @@
{{ page.title }} | {{ site.site_title }}
-
+
@@ -15,7 +15,7 @@
-
-
+
+
diff --git a/docs/_plugins/rule_tag.rb b/docs/_plugins/rule_tag.rb
index 36eeb12032..7b5aa3ee13 100644
--- a/docs/_plugins/rule_tag.rb
+++ b/docs/_plugins/rule_tag.rb
@@ -53,7 +53,7 @@ class RuleTag < Liquid::Tag
# This is passed from the release notes processing script
# When generating links for the release notes, the links should be absolute
if context["is_release_notes_processor"]
- url_prefix = "https://pmd.github.io/pmd-#{context["site.pmd.version"]}/"
+ url_prefix = "https://docs.pmd-code.org/pmd-doc-#{context["site.pmd.version"]}/"
end
if @was_removed
diff --git a/docs/assets/README.md b/docs/assets/README.md
index 947fb59af0..48125954f8 100644
--- a/docs/assets/README.md
+++ b/docs/assets/README.md
@@ -4,7 +4,7 @@
Doc: https://fontawesome.com/how-to-use/on-the-web/setup/hosting-font-awesome-yourself
-Download: https://use.fontawesome.com/releases/v5.14.0/fontawesome-free-5.14.0-web.zip
+Download: https://use.fontawesome.com/releases/v5.15.4/fontawesome-free-5.15.4-web.zip
## Bootstrap
diff --git a/docs/assets/fontawesome-free-5.14.0-web/css/all.min.css b/docs/assets/fontawesome-free-5.14.0-web/css/all.min.css
deleted file mode 100644
index f7eacc802d..0000000000
--- a/docs/assets/fontawesome-free-5.14.0-web/css/all.min.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/*!
- * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
- * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
- */
-.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900}
\ No newline at end of file
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.eot b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.eot
deleted file mode 100644
index 54ad8d72dc..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.eot and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.ttf b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.ttf
deleted file mode 100644
index 16852bfd05..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.ttf and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.woff b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.woff
deleted file mode 100644
index 6cf6fb3870..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.woff and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.woff2 b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.woff2
deleted file mode 100644
index f2a4e36f18..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.woff2 and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.eot b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.eot
deleted file mode 100644
index 479b32cecc..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.eot and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.ttf b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.ttf
deleted file mode 100644
index 42a04fde4e..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.ttf and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.woff b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.woff
deleted file mode 100644
index c390c60e2b..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.woff and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.woff2 b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.woff2
deleted file mode 100644
index 11c71d28cf..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-regular-400.woff2 and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.eot b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.eot
deleted file mode 100644
index 52883b93c8..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.eot and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.ttf b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.ttf
deleted file mode 100644
index 7c59512f3c..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.ttf and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.woff b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.woff
deleted file mode 100644
index aff125d658..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.woff and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.woff2 b/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.woff2
deleted file mode 100644
index aa2b79109e..0000000000
Binary files a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-solid-900.woff2 and /dev/null differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/LICENSE.txt b/docs/assets/fontawesome-free-5.15.4-web/LICENSE.txt
similarity index 100%
rename from docs/assets/fontawesome-free-5.14.0-web/LICENSE.txt
rename to docs/assets/fontawesome-free-5.15.4-web/LICENSE.txt
diff --git a/docs/assets/fontawesome-free-5.15.4-web/css/all.min.css b/docs/assets/fontawesome-free-5.15.4-web/css/all.min.css
new file mode 100644
index 0000000000..ac76ff191e
--- /dev/null
+++ b/docs/assets/fontawesome-free-5.15.4-web/css/all.min.css
@@ -0,0 +1,5 @@
+/*!
+ * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ */
+.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hive:before{content:"\e07f"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-innosoft:before{content:"\e080"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-perbyte:before{content:"\e083"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-uncharted:before{content:"\e084"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-vest:before{content:"\e085"}.fa-vest-patches:before{content:"\e086"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-watchman-monitoring:before{content:"\e087"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900}
\ No newline at end of file
diff --git a/docs/assets/fontawesome-free-5.15.4-web/webfonts/fa-brands-400.eot b/docs/assets/fontawesome-free-5.15.4-web/webfonts/fa-brands-400.eot
new file mode 100644
index 0000000000..cba6c6cce8
Binary files /dev/null and b/docs/assets/fontawesome-free-5.15.4-web/webfonts/fa-brands-400.eot differ
diff --git a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.svg b/docs/assets/fontawesome-free-5.15.4-web/webfonts/fa-brands-400.svg
similarity index 95%
rename from docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.svg
rename to docs/assets/fontawesome-free-5.15.4-web/webfonts/fa-brands-400.svg
index 2c8659c12b..b9881a43b7 100644
--- a/docs/assets/fontawesome-free-5.14.0-web/webfonts/fa-brands-400.svg
+++ b/docs/assets/fontawesome-free-5.15.4-web/webfonts/fa-brands-400.svg
@@ -1,16 +1,12 @@
-
This section lists the most important changes from the last release candidate.
The remaining section describe the complete release notes for 7.0.0.
-Fixed Issues:
+#### API Changes
+* Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from
+ `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and
+ are base classes for CPD language implementations.
+* `AntlrBaseRule` is gone in favor of {% jdoc core::lang.rule.AbstractVisitorRule %}.
+* The classes {% jdoc kotlin::lang.kotlin.ast.KotlinInnerNode %} and {% jdoc swift::lang.swift.ast.SwiftInnerNode %}
+ are package-private now.
+* The parameter order of {% jdoc core::lang.document.FileCollector#addSourceFile(String, String) %} has been swapped
+ in order to have the same meaning as in 6.55.0. That will make it easier if you upgrade from 6.55.0 to 7.0.0.
+ However, that means, that you need to change these method calls if you have migrated to 7.0.0-rc1 already.
+
+#### Updated PMD Designer
+This PMD release ships a new version of the pmd-designer.
+For the changes, see [PMD Designer Changelog](https://github.com/pmd/pmd-designer/releases/tag/7.0.0-rc1).
+
+#### Rule Changes
+* {% rule "java/design/ImmutableField" %}: the property `ignoredAnnotations` has been removed. The property was
+ deprecated since PMD 6.52.0.
+
+#### Fixed Issues
+* cli
+ * [#4482](https://github.com/pmd/pmd/issues/4482): \[cli] pmd.bat can only be executed once
+ * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE
+* core
+ * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages
+* doc
+ * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation
+ * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated
* java-codestyle
* [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default
+ * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired
+* java-design
+ * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter
+ * [#4477](https://github.com/pmd/pmd/issues/4477): \[java] SignatureDeclareThrowsException: false-positive with TestNG annotations
+ * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter
* java-errorprone
* [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression
+ * [#4493](https://github.com/pmd/pmd/issues/4493): \[java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject
+ * [#4505](https://github.com/pmd/pmd/issues/4505): \[java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1
+* java-multithreading
+ * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking
+* miscellaneous
+ * [#4462](https://github.com/pmd/pmd/issues/4462): Provide Software Bill of Materials (SBOM)
+
+#### External contributions
+* [#4444](https://github.com/pmd/pmd/pull/4444): \[java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - [Nirvik Patel](https://github.com/nirvikpatel) (@nirvikpatel)
+* [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999)
+* [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm)
+* [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos)
+* [#4488](https://github.com/pmd/pmd/pull/4488): \[java] Fix #4477: A false-positive about SignatureDeclareThrowsException - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe)
+* [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe)
+* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe)
+* [#4520](https://github.com/pmd/pmd/pull/4520): \[doc] Fix typo: missing closing quotation mark after CPD-END - [João Dinis Ferreira](https://github.com/joaodinissf) (@joaodinissf)
### 🚀 Major Features and Enhancements
@@ -60,7 +108,7 @@ The new official logo of PMD:
* Rewritten type resolution framework and symbol table correctly implements the JLS
* AST exposes more semantic information (method calls, field accesses)
-For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
+For more information, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html).
Contributors: [Clément Fournier](https://github.com/oowekyala) (@oowekyala),
[Andreas Dangel](https://github.com/adangel) (@adangel),
@@ -78,7 +126,7 @@ Contributors: [Clément Fournier](https://github.com/oowekyala) (@oowekyala),

-For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
+For more information, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html).
Contributors: [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod)
@@ -88,16 +136,21 @@ Contributors: [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuy
* Previously, Antlr grammar could only be used for CPD
* New supported languages: Swift and Kotlin
-For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
+For more information, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html).
Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini),
[Matías Fraga](https://github.com/matifraga) (@matifraga),
[Tomás De Lucca](https://github.com/tomidelucca) (@tomidelucca)
+#### Updated PMD Designer
+
+This PMD release ships a new version of the pmd-designer.
+For the changes, see [PMD Designer Changelog](https://github.com/pmd/pmd-designer/releases/tag/7.0.0-rc1).
+
### 🎉 Language Related Changes
Note that this is just a concise listing of the highlight.
-For more information on the languages, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
+For more information on the languages, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html).
#### New: Swift support
@@ -114,6 +167,20 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini),
* Support for Kotlin 1.8 grammar
* initially 2 built-in rules
+#### New: CPD support for TypeScript
+
+Thanks to a contribution, CPD now supports the TypeScript language. It is shipped
+with the rest of the JavaScript support in the module `pmd-javascript`.
+
+Contributors: [Paul Guyot](https://github.com/pguyot) (@pguyot)
+
+#### New: CPD support for Julia
+
+Thanks to a contribution, CPD now supports the Julia language. It is shipped
+in the new module `pmd-julia`.
+
+Contributors: [Wener](https://github.com/wener-tiobe) (@wener-tiobe)
+
#### Changed: JavaScript support
* latest version supports ES6 and also some new constructs (see [Rhino](https://github.com/mozilla/rhino)])
@@ -172,11 +239,13 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini),
* {% rule "java/documentation/CommentContent" %}: The properties `caseSensitive` and `disallowedTerms` are removed. The
new property `fobiddenRegex` can be used now to define the disallowed terms with a single regular
expression.
+* {% rule "java/design/ImmutableField" %}: the property `ignoredAnnotations` has been removed. The property was
+ deprecated since PMD 6.52.0.
#### Removed Rules
Many rules, that were previously deprecated have been finally removed.
-See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html) for the complete list.
+See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html) for the complete list.
### 🚨 API
@@ -185,7 +254,7 @@ have a clear separation between a well-defined API and the implementation, which
This should help us in future development.
Also, there are some improvement and changes in different areas. For the detailed description
-of the changes listed here, see [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
+of the changes listed here, see [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html).
* Miscellaneous smaller changes and cleanups
* XPath 3.1 support for XPath-based rules
@@ -195,7 +264,7 @@ of the changes listed here, see [Detailed Release Notes for PMD 7](pmd_release_n
* Language Lifecycle and Language Properties
### 💥 Compatibility and migration notes
-See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
+See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html).
### 🐛 Fixed Issues
@@ -208,6 +277,7 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
* [#2497](https://github.com/pmd/pmd/issues/2497): PMD 7 Logo page
* [#2498](https://github.com/pmd/pmd/issues/2498): Update PMD 7 Logo in documentation
* [#3797](https://github.com/pmd/pmd/issues/3797): \[all] Use JUnit5
+ * [#4462](https://github.com/pmd/pmd/issues/4462): Provide Software Bill of Materials (SBOM)
* ant
* [#4080](https://github.com/pmd/pmd/issues/4080): \[ant] Split off Ant integration into a new submodule
* core
@@ -220,6 +290,7 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
* [#2218](https://github.com/pmd/pmd/issues/2218): \[core] `isFindBoundary` should not be an attribute
* [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command
* [#2239](https://github.com/pmd/pmd/issues/2239): \[core] Merging Javacc build scripts
+ * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages
* [#2518](https://github.com/pmd/pmd/issues/2518): \[core] Language properties
* [#2602](https://github.com/pmd/pmd/issues/2602): \[core] Remove ParserOptions
* [#2614](https://github.com/pmd/pmd/pull/2614): \[core] Upgrade Saxon, add XPath 3.1, remove Jaxen
@@ -244,6 +315,11 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
* [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command
* [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting
* [#4079](https://github.com/pmd/pmd/issues/4079): \[cli] Split off CLI implementation into a pmd-cli submodule
+ * [#4482](https://github.com/pmd/pmd/issues/4482): \[cli] pmd.bat can only be executed once
+ * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE
+* doc
+ * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation
+ * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated
* testing
* [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module
* [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work
@@ -274,6 +350,7 @@ Language specific fixes:
* [#1661](https://github.com/pmd/pmd/issues/1661): \[java] About operator nodes
* [#2366](https://github.com/pmd/pmd/pull/2366): \[java] Remove qualified names
* [#2819](https://github.com/pmd/pmd/issues/2819): \[java] GLB bugs in pmd 7
+ * [#3642](https://github.com/pmd/pmd/issues/3642): \[java] Parse error on rare extra dimensions on method return type on annotation methods
* [#3763](https://github.com/pmd/pmd/issues/3763): \[java] Ambiguous reference error in valid code
* [#3749](https://github.com/pmd/pmd/issues/3749): \[java] Improve `isOverridden` in ASTMethodDeclaration
* [#3750](https://github.com/pmd/pmd/issues/3750): \[java] Make symbol table support instanceof pattern bindings
@@ -291,7 +368,9 @@ Language specific fixes:
* [#1189](https://github.com/pmd/pmd/issues/1189): \[java] UnusedPrivateMethod false positive from inner class via external class
* [#1205](https://github.com/pmd/pmd/issues/1205): \[java] Improve ConstantsInInterface message to mention alternatives
* [#1212](https://github.com/pmd/pmd/issues/1212): \[java] Don't raise JUnitTestContainsTooManyAsserts on JUnit 5's assertAll
- * [#1422](https://github.com/pmd/pmd/issues/1422): \[java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
+ * [#1422](https://github.com/pmd/pmd/issues/1422): \[java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
+ * [#1455](https://github.com/pmd/pmd/issues/1455): \[java] JUnitTestsShouldIncludeAssert: False positives for assert methods named "check" and "verify"
+ * [#1563](https://github.com/pmd/pmd/issues/1563): \[java] False positive ForLoopCanBeForeach
* [#1565](https://github.com/pmd/pmd/issues/1565): \[java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ
* [#1747](https://github.com/pmd/pmd/issues/1747): \[java] PreserveStackTrace false-positive
* [#1969](https://github.com/pmd/pmd/issues/1969): \[java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class
@@ -312,9 +391,11 @@ Language specific fixes:
* [#2946](https://github.com/pmd/pmd/issues/2946): \[java] SwitchStmtsShouldHaveDefault false positive on enum inside enums
* [#3672](https://github.com/pmd/pmd/pull/3672): \[java] LooseCoupling - fix false positive with generics
* [#3675](https://github.com/pmd/pmd/pull/3675): \[java] MissingOverride - fix false positive with mixing type vars
+ * [#3858](https://github.com/pmd/pmd/issues/3858): \[java] UseCollectionIsEmpty should infer local variable type from method invocation
* java-codestyle
* [#1208](https://github.com/pmd/pmd/issues/1208): \[java] PrematureDeclaration rule false-positive on variable declared to measure time
* [#1429](https://github.com/pmd/pmd/issues/1429): \[java] PrematureDeclaration as result of method call (false positive)
+ * [#1480](https://github.com/pmd/pmd/issues/1480): \[java] IdenticalCatchBranches false positive
* [#1673](https://github.com/pmd/pmd/issues/1673): \[java] UselessParentheses false positive with conditional operator
* [#1790](https://github.com/pmd/pmd/issues/1790): \[java] UnnecessaryFullyQualifiedName false positive with enum constant
* [#1918](https://github.com/pmd/pmd/issues/1918): \[java] UselessParentheses false positive with boolean operators
@@ -332,9 +413,11 @@ Language specific fixes:
* [#3500](https://github.com/pmd/pmd/pull/3500): \[java] UnnecessaryBoxing - check for Integer.valueOf(String) calls
* [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default
* [#4357](https://github.com/pmd/pmd/pull/4357): \[java] Fix IllegalStateException in UseDiamondOperator rule
+ * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired
* java-design
* [#1014](https://github.com/pmd/pmd/issues/1014): \[java] LawOfDemeter: False positive with lambda expression
* [#1605](https://github.com/pmd/pmd/issues/1605): \[java] LawOfDemeter: False positive for standard UTF-8 charset name
+ * [#2160](https://github.com/pmd/pmd/issues/2160): \[java] Issues with Law of Demeter
* [#2175](https://github.com/pmd/pmd/issues/2175): \[java] LawOfDemeter: False positive for chained methods with generic method call
* [#2179](https://github.com/pmd/pmd/issues/2179): \[java] LawOfDemeter: False positive with static property access - should treat class-level property as global object, not dot-accessed property
* [#2180](https://github.com/pmd/pmd/issues/2180): \[java] LawOfDemeter: False positive with Thread and ThreadLocalRandom
@@ -345,6 +428,9 @@ Language specific fixes:
* [#3754](https://github.com/pmd/pmd/issues/3754): \[java] SingularField false positive with read in while condition
* [#3786](https://github.com/pmd/pmd/issues/3786): \[java] SimplifyBooleanReturns should consider operator precedence
* [#4238](https://github.com/pmd/pmd/pull/4238): \[java] Make LawOfDemeter not use the rulechain
+ * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter
+ * [#4477](https://github.com/pmd/pmd/issues/4477): \[java] SignatureDeclareThrowsException: false-positive with TestNG annotations
+ * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter
* java-documentation
* [#4369](https://github.com/pmd/pmd/pull/4369): \[java] Improve CommentSize
* [#4416](https://github.com/pmd/pmd/pull/4416): \[java] Fix reported line number in CommentContentRule
@@ -352,7 +438,7 @@ Language specific fixes:
* [#659](https://github.com/pmd/pmd/issues/659): \[java] MissingBreakInSwitch - last default case does not contain a break
* [#1005](https://github.com/pmd/pmd/issues/1005): \[java] CloneMethodMustImplementCloneable triggers for interfaces
* [#1669](https://github.com/pmd/pmd/issues/1669): \[java] NullAssignment - FP with ternay and null as constructor argument
- * [#1899](https://github.com/pmd/pmd/issues/1899): \[java] Recognize @SuppressWanings("fallthrough") for MissingBreakInSwitch
+ * [#1899](https://github.com/pmd/pmd/issues/1899): \[java] Recognize @SuppressWanings("fallthrough") for MissingBreakInSwitch
* [#2320](https://github.com/pmd/pmd/issues/2320): \[java] NullAssignment - FP with ternary and null as method argument
* [#2532](https://github.com/pmd/pmd/issues/2532): \[java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case `new BigDecimal(Expression)`
* [#2579](https://github.com/pmd/pmd/issues/2579): \[java] MissingBreakInSwitch detects the lack of break in the last case
@@ -365,17 +451,22 @@ Language specific fixes:
* [#3173](https://github.com/pmd/pmd/issues/3173): \[java] UseProperClassLoader false positive
* [#3351](https://github.com/pmd/pmd/issues/3351): \[java] ConstructorCallsOverridableMethod ignores abstract methods
* [#3400](https://github.com/pmd/pmd/issues/3400): \[java] AvoidUsingOctalValues FN with underscores
+ * [#3843](https://github.com/pmd/pmd/issues/3843): \[java] UseEqualsToCompareStrings should consider return type
* [#4356](https://github.com/pmd/pmd/pull/4356): \[java] Fix NPE in CloseResourceRule
* [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression
+ * [#4493](https://github.com/pmd/pmd/issues/4493): \[java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject
+ * [#4505](https://github.com/pmd/pmd/issues/4505): \[java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1
* java-multithreading
* [#2537](https://github.com/pmd/pmd/issues/2537): \[java] DontCallThreadRun can't detect the case that call run() in `this.run()`
* [#2538](https://github.com/pmd/pmd/issues/2538): \[java] DontCallThreadRun can't detect the case that call run() in `foo.bar.run()`
* [#2577](https://github.com/pmd/pmd/issues/2577): \[java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: `foo.notify(bar)`
+ * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking
* java-performance
* [#1224](https://github.com/pmd/pmd/issues/1224): \[java] InefficientEmptyStringCheck false negative in anonymous class
* [#2587](https://github.com/pmd/pmd/issues/2587): \[java] AvoidArrayLoops could also check for list copy through iterated List.add()
* [#2712](https://github.com/pmd/pmd/issues/2712): \[java] SimplifyStartsWith false-positive with AssertJ
* [#3486](https://github.com/pmd/pmd/pull/3486): \[java] InsufficientStringBufferDeclaration: Fix NPE
+ * [#3848](https://github.com/pmd/pmd/issues/3848): \[java] StringInstantiation: false negative when using method result
* kotlin
* [#419](https://github.com/pmd/pmd/issues/419): \[kotlin] Add support for Kotlin
* [#4389](https://github.com/pmd/pmd/pull/4389): \[kotlin] Update grammar to version 1.8
@@ -395,10 +486,18 @@ Language specific fixes:
* [#1882](https://github.com/pmd/pmd/pull/1882): \[swift] UnavailableFunction Swift rule - [Tomás de Lucca](https://github.com/tomidelucca) (@tomidelucca)
* [#2830](https://github.com/pmd/pmd/pull/2830): \[apex] Apexlink POC - [Kevin Jones](https://github.com/nawforce) (@nawforce)
* [#3866](https://github.com/pmd/pmd/pull/3866): \[core] Add CLI Progress Bar - [@JerritEic](https://github.com/JerritEic) (@JerritEic)
+* [#4402](https://github.com/pmd/pmd/pull/4402): \[javascript] CPD: add support for Typescript using antlr4 grammar - [Paul Guyot](https://github.com/pguyot) (@pguyot)
+* [#4403](https://github.com/pmd/pmd/pull/4403): \[julia] CPD: Add support for Julia code duplication - [Wener](https://github.com/wener-tiobe) (@wener-tiobe)
* [#4412](https://github.com/pmd/pmd/pull/4412): \[doc] Added new error msg to ConstantsInInterface - [David Ljunggren](https://github.com/dague1) (@dague1)
* [#4428](https://github.com/pmd/pmd/pull/4428): \[apex] ApexBadCrypto bug fix for #4427 - inline detection of hard coded values - [Steven Stearns](https://github.com/sfdcsteve) (@sfdcsteve)
* [#4444](https://github.com/pmd/pmd/pull/4444): \[java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - [Nirvik Patel](https://github.com/nirvikpatel) (@nirvikpatel)
* [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999)
+* [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm)
+* [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos)
+* [#4488](https://github.com/pmd/pmd/pull/4488): \[java] Fix #4477: A false-positive about SignatureDeclareThrowsException - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe)
+* [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe)
+* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe)
+* [#4520](https://github.com/pmd/pmd/pull/4520): \[doc] Fix typo: missing closing quotation mark after CPD-END - [João Dinis Ferreira](https://github.com/joaodinissf) (@joaodinissf)
### 📈 Stats
* 4416 commits
diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md
index 7b05d6ff5b..acece18793 100644
--- a/docs/pages/release_notes_old.md
+++ b/docs/pages/release_notes_old.md
@@ -12,7 +12,7 @@ Previous versions of PMD can be downloaded here: https://github.com/pmd/pmd/rele
We're excited to bring you the next major version of PMD!
Since this is a big release, we provide here only a concise version of the release notes. We prepared a separate
-page with the full [Detailed Release Notes for PMD 7.0.0](https://pmd.github.io/pmd-7.0.0-rc1/pmd_release_notes_pmd7.html).
+page with the full [Detailed Release Notes for PMD 7.0.0](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_release_notes_pmd7.html).
ℹ️ Release Candidates
@@ -57,7 +57,7 @@ for all.
The new official logo of PMD:
-
+
#### Revamped Java module
@@ -82,7 +82,7 @@ Contributors: [Clément Fournier](https://github.com/oowekyala) (@oowekyala),
* progress bar support for `pmd check`
* shell completion
-
+
For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html).
@@ -136,46 +136,46 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini),
#### New Rules
**Apex**
-* [`UnusedMethod`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_apex_design.html#unusedmethod) finds unused methods in your code.
+* [`UnusedMethod`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_apex_design.html#unusedmethod) finds unused methods in your code.
**Java**
-* [`UnnecessaryBoxing`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryboxing) reports boxing and unboxing conversions that may be made implicit.
+* [`UnnecessaryBoxing`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryboxing) reports boxing and unboxing conversions that may be made implicit.
**Kotlin**
-* [`FunctionNameTooShort`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_kotlin_bestpractices.html#functionnametooshort)
-* [`OverrideBothEqualsAndHashcode`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_kotlin_errorprone.html#overridebothequalsandhashcode)
+* [`FunctionNameTooShort`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_kotlin_bestpractices.html#functionnametooshort)
+* [`OverrideBothEqualsAndHashcode`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_kotlin_errorprone.html#overridebothequalsandhashcode)
**Swift**
-* [`ProhibitedInterfaceBuilder`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder)
-* [`UnavailableFunction`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_bestpractices.html#unavailablefunction)
-* [`ForceCast`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcecast)
-* [`ForceTry`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcetry)
+* [`ProhibitedInterfaceBuilder`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder)
+* [`UnavailableFunction`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_bestpractices.html#unavailablefunction)
+* [`ForceCast`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcecast)
+* [`ForceTry`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcetry)
#### Changed Rules
**Java**
-* [`UnnecessaryFullyQualifiedName`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryfullyqualifiedname): the rule has two new properties,
+* [`UnnecessaryFullyQualifiedName`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryfullyqualifiedname): the rule has two new properties,
to selectively disable reporting on static field and method qualifiers. The rule also has been improved
to be more precise.
-* [`UselessParentheses`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#uselessparentheses): the rule has two new properties which control how strict
+* [`UselessParentheses`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#uselessparentheses): the rule has two new properties which control how strict
the rule should be applied. With `ignoreClarifying` (default: true) parentheses that are strictly speaking
not necessary are allowed, if they separate expressions of different precedence.
The other property `ignoreBalancing` (default: true) is similar, in that it allows parentheses that help
reading and understanding the expressions.
-* [`LooseCoupling`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_bestpractices.html#loosecoupling): the rule has a new property to allow some types to be coupled
+* [`LooseCoupling`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_bestpractices.html#loosecoupling): the rule has a new property to allow some types to be coupled
to (`allowedTypes`).
-* [`EmptyCatchBlock`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_errorprone.html#emptycatchblock): `CloneNotSupportedException` and `InterruptedException` are not
+* [`EmptyCatchBlock`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_errorprone.html#emptycatchblock): `CloneNotSupportedException` and `InterruptedException` are not
special-cased anymore. Rename the exception parameter to `ignored` to ignore them.
-* [`DontImportSun`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_errorprone.html#dontimportsun): `sun.misc.Signal` is not special-cased anymore.
-* [`UseDiamondOperator`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#usediamondoperator): the property `java7Compatibility` is removed. The rule now
+* [`DontImportSun`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_errorprone.html#dontimportsun): `sun.misc.Signal` is not special-cased anymore.
+* [`UseDiamondOperator`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#usediamondoperator): the property `java7Compatibility` is removed. The rule now
handles Java 7 properly without a property.
-* [`SingularField`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_design.html#singularfield): Properties `checkInnerClasses` and `disallowNotAssignment` are removed.
+* [`SingularField`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_design.html#singularfield): Properties `checkInnerClasses` and `disallowNotAssignment` are removed.
The rule is now more precise and will check these cases properly.
-* [`UseUtilityClass`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_design.html#useutilityclass): The property `ignoredAnnotations` has been removed.
-* [`LawOfDemeter`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_design.html#lawofdemeter): the rule has a new property `trustRadius`. This defines the maximum degree
+* [`UseUtilityClass`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_design.html#useutilityclass): The property `ignoredAnnotations` has been removed.
+* [`LawOfDemeter`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_design.html#lawofdemeter): the rule has a new property `trustRadius`. This defines the maximum degree
of trusted data. The default of 1 is the most restrictive.
-* [`CommentContent`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_documentation.html#commentcontent): The properties `caseSensitive` and `disallowedTerms` are removed. The
+* [`CommentContent`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_documentation.html#commentcontent): The properties `caseSensitive` and `disallowedTerms` are removed. The
new property `fobiddenRegex` can be used now to define the disallowed terms with a single regular
expression.
@@ -453,6 +453,7 @@ version `20-preview`:
./run.sh pmd --use-version java-20-preview ...
#### T-SQL support
+
Thanks to the contribution from [Paul Guyot](https://github.com/pguyot) PMD now has CPD support
for T-SQL (Transact-SQL).
diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md
index 9f74c26e59..08f285d210 100644
--- a/docs/pages/release_notes_pmd7.md
+++ b/docs/pages/release_notes_pmd7.md
@@ -441,6 +441,11 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini),
[Matías Fraga](https://github.com/matifraga) (@matifraga),
[Tomás De Lucca](https://github.com/tomidelucca) (@tomidelucca)
+### Updated PMD Designer
+
+This PMD release ships a new version of the pmd-designer.
+For the changes, see [PMD Designer Changelog](https://github.com/pmd/pmd-designer/releases/tag/7.0.0-rc1).
+
## 🎉 Language Related Changes
### New: Swift support
@@ -550,6 +555,8 @@ Related issue: [[core] Explicitly name all language versions (#4120)](https://gi
* {% rule "java/documentation/CommentContent" %}: The properties `caseSensitive` and `disallowedTerms` are removed. The
new property `fobiddenRegex` can be used now to define the disallowed terms with a single regular
expression.
+* {% rule "java/design/ImmutableField" %}: the property `ignoredAnnotations` has been removed. The property was
+ deprecated since PMD 6.52.0.
### Deprecated Rules
@@ -750,6 +757,13 @@ until the next major release, but it is recommended to stop using them.
* {% jdoc core::util.IteratorUtil %}
* {% jdoc core::util.StringUtil %}
+* Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from
+ `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and
+ are base classes for CPD language implementations. Since 7.0.0-rc2.
+* `AntlrBaseRule` is gone in favor of {% jdoc core::lang.rule.AbstractVisitorRule %}. Since 7.0.0-rc2.
+* The classes {% jdoc kotlin::lang.kotlin.ast.KotlinInnerNode %} and {% jdoc swift::lang.swift.ast.SwiftInnerNode %}
+ are package-private now. Since 7.0.0-rc2.
+
### XPath 3.1 support
Support for XPath versions 1.0, 1.0-compatibility was removed, support for XPath 2.0 is deprecated. The default
diff --git a/docs/report-examples/pmd-report.sarif.json b/docs/report-examples/pmd-report.sarif.json
index e785af258d..005c000c90 100644
--- a/docs/report-examples/pmd-report.sarif.json
+++ b/docs/report-examples/pmd-report.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": [
{
"id": "ApexSharingViolations",
@@ -17,7 +17,7 @@
"fullDescription": {
"text": "Detect classes declared without explicit sharing mode if DML methods are used. This forces the developer to take access restrictions into account before modifying objects."
},
- "helpUri": "https://pmd.github.io/pmd/pmd_rules_apex_security.html#apexsharingviolations",
+ "helpUri": "https://docs.pmd-code.org/latest/pmd_rules_apex_security.html#apexsharingviolations",
"help": {
"text": "Detect classes declared without explicit sharing mode if DML methods are used. This forces the developer to take access restrictions into account before modifying objects."
},
@@ -37,7 +37,7 @@
"fullDescription": {
"text": "This rule validates that: ApexDoc comments are present for classes, methods, and properties that are public or global, excluding overrides and test classes (as well as the contents of test classes)."
},
- "helpUri": "https://pmd.github.io/pmd/pmd_rules_apex_documentation.html#apexdoc",
+ "helpUri": "https://docs.pmd-code.org/latest/pmd_rules_apex_documentation.html#apexdoc",
"help": {
"text": "This rule validates that: ApexDoc comments are present for classes, methods, and properties that are public or global, excluding overrides and test classes (as well as the contents of test classes)."
},
@@ -152,4 +152,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index 38a04d6c4e..5a1d7dc52e 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -1,24 +1,42 @@
---
layout: none
search: exclude
+# https://www.sitemaps.org/protocol.html
+# Priority is relative to the website, can be chosen in {0.1, 0.2, ..., 1}
+# Default priority is 0.5
+latestPriority: 0.8
---
+
+ {{site.url}}/index.html
+ 0.9
+ monthly
+ {{ site.time | date: "%Y-%m-%d" }}
+
+
+
{% for post in site.posts %}
{% unless post.search == "exclude" %}
{{site.url}}{{post.url}}
+ {{page.latestPriority}}
+ monthly
+ {{ site.time | date: "%Y-%m-%d" }}
{% endunless %}
{% endfor %}
- {% for page in site.pages %}
- {% unless page.search == "exclude" %}
+ {% for p in site.pages %}
+ {% unless p.search == "exclude" %}
- {{site.url}}{{ page.url}}
+ {{site.url}}{{ p.url}}
+ {{page.latestPriority}}
+ monthly
+ {{ site.time | date: "%Y-%m-%d" }}
{% endunless %}
{% endfor %}
-
\ No newline at end of file
+
diff --git a/docs/sitemap_generator.sh b/docs/sitemap_generator.sh
deleted file mode 100755
index 03e25a0bcf..0000000000
--- a/docs/sitemap_generator.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env bash
-
-# Sitemap generator for pmd.github.io main landing page.
-# Assumes we have the latest version of the site under "latest"
-# https://www.sitemaps.org/protocol.html
-
-WEBSITE_PREFIX="https://pmd.github.io/"
-DOC_PREFIX="latest/"
-DATE=`date +%Y-%m-%d`
-# Priority is relative to the website, can be chosen in {0.1, 0.2, ..., 1}
-# Default priority is 0.5
-LATEST_PRIORITY=0.8
-
-
-# Writes to standard output
-
-cat << HEADER_END
-
-
-
-
- ${WEBSITE_PREFIX}index.html
- 1
- monthly
- $DATE
-
-
-
- ${WEBSITE_PREFIX}${DOC_PREFIX}index.html
- 0.9
- monthly
- $DATE
-
-
-
-
-HEADER_END
-
-
-for page in ${DOC_PREFIX}pmd_*.html
-do
-
- cat << ENTRY_END
-
- ${WEBSITE_PREFIX}$page
- $LATEST_PRIORITY
- monthly
- $DATE
-
-
-ENTRY_END
-
-done
-
-echo ""
-
diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java
index a9aebddf01..335fb06084 100644
--- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java
+++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java
@@ -71,7 +71,16 @@ public final class ApexMultifileAnalysis {
// FIXME: Syntax & Semantic errors found during Org loading are not currently being reported. These
// should be routed to the new SemanticErrorReporter but that is not available for use just yet.
}
- } catch (Exception e) {
+ } catch (Exception | ExceptionInInitializerError | NoClassDefFoundError e) {
+ // Note: Org.newOrg() will try to find the base Apex Types through the current classloader
+ // in package "com.nawforce.runforce". This requires, that directory listings can be retrievied
+ // on the URL that the classloader returns from getResource("/com/nawforce/runforce"):
+ // https://github.com/nawforce/apex-link/blob/7688adcb7a2d7f8aa28d0618ffb2a3aa81151858/apexlink/src/main/scala/com/nawforce/apexlink/types/platform/PlatformTypeDeclaration.scala#L260-L273
+ // However, when running as an Eclipse plugin, we have a special bundle classloader, that returns
+ // URIs in the form "bundleresource://...". For the schema "bundleresource", no FileSystemProvider can be
+ // found, so we get a java.nio.file.ProviderNotFoundException. Since all this happens during initialization of the class
+ // com.nawforce.apexlink.types.platform.PlatformTypeDeclaration we get a ExceptionInInitializerError
+ // and later NoClassDefFoundErrors, because PlatformTypeDeclaration couldn't be loaded.
LOG.error("Exception while initializing Apexlink ({})", e.getMessage(), e);
LOG.error("PMD will not attempt to initialize Apexlink further, this can cause rules like UnusedMethod to be dysfunctional");
org = null;
diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java
index 5be16d0783..b833424ced 100644
--- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java
+++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java
@@ -52,4 +52,8 @@ public class ExcessivePublicCountRule extends AbstractCounterCheckRule {
protected boolean isIgnored(ASTMethod node) {
return node.isConstructor();
}
+
+ @Override
+ protected Object[] getViolationParameters(ASTMethod node, int metric, int limit) {
+ return new Object[]{ node.getImage(), metric, limit };
+ }
}
diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java
index 8e4ff77025..3879f3fd07 100644
--- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java
+++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java
@@ -48,9 +48,8 @@ public abstract class AbstractCounterCheckRule> extends Ab
protected abstract int defaultReportLevel();
-
- protected Object[] getViolationParameters(T node, int metric) {
- return new Object[] {metric};
+ protected Object[] getViolationParameters(T node, int metric, int limit) {
+ return new Object[] {metric, limit};
}
@@ -70,8 +69,9 @@ public abstract class AbstractCounterCheckRule> extends Ab
if (!isIgnored(t)) {
int metric = getMetric(t);
- if (metric >= getProperty(reportLevel)) {
- addViolation(data, node, getViolationParameters(t, metric));
+ int limit = getProperty(reportLevel);
+ if (metric >= limit) {
+ addViolation(data, node, getViolationParameters(t, metric, limit));
}
}
diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml
index 6f34471e41..808ceb08b7 100644
--- a/pmd-apex/src/main/resources/category/apex/design.xml
+++ b/pmd-apex/src/main/resources/category/apex/design.xml
@@ -48,13 +48,13 @@ Avoid having unused methods since they make understanding and maintaining code h
This rule finds not only unused private methods, but public methods as well.
[ApexLink](https://github.com/nawforce/ApexLink) is used to make this possible and this needs
-additional configuration. The environment variable `PMD_APEX_ROOTDIRECTORY` needs to be set prior to executing
+additional configuration. The environment variable `PMD_APEX_ROOT_DIRECTORY` needs to be set prior to executing
PMD. With this variable the root directory of the Salesforce metadata, where `sfdx-project.json` resides, is
specified. ApexLink can then load all the classes in the project and figure out, whether a method is used or not.
-For an accurate analysis it is important that the `PMD_APEX_ROOTDIRECTORY` contains a complete set of metadata that
+For an accurate analysis it is important that the `PMD_APEX_ROOT_DIRECTORY` contains a complete set of metadata that
may be referenced from the Apex source code, such as Custom Objects, Visualforce Pages, Flows and Labels. The
-`PMD_APEX_ROOTDIRECTORY` directory must contain a `sfdx-project.json`, but metadata may be either in the
+`PMD_APEX_ROOT_DIRECTORY` directory must contain a `sfdx-project.json`, but metadata may be either in the
[SFDX Source format](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_source_file_format.htm)
or the older MDAPI format. The `packageDirectories` entries in `sfdx-project.json` are used to determine which
directories to search for metadata, if a `.forceignore` file is present it will be respected.
@@ -281,7 +281,7 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
@@ -340,7 +340,7 @@ public class Foo extends Bar {
diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml
index 45e7fe4a93..b424122e23 100644
--- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml
+++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml
@@ -113,4 +113,29 @@ public class SomeClass {
}
]]>
+
+
+ class with inner classes
+ 1
+ 2
+ 1,5
+
+ The class OuterClass has 2 public methods and attributes (limit: 1)
+ The class InnerClass has 4 public methods and attributes (limit: 1)
+
+
+
diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml
index 6562dcb876..b278b7299b 100644
--- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml
+++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml
@@ -70,6 +70,9 @@ public class Foo {
long method131
+
+ The method 'foo()' has an NCSS line count of 13 (limit: 13)
+
diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml
index 5d65824a77..a144afdd06 100644
--- a/pmd-cli/pom.xml
+++ b/pmd-cli/pom.xml
@@ -78,168 +78,15 @@
${project.version}
-
-
+
net.sourceforge.pmd
- pmd-apex
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-cpp
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-cs
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-dart
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-fortran
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-gherkin
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-go
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-groovy
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-html
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-lua
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-java
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-javascript
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-jsp
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-kotlin
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-matlab
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-modelica
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-perl
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-objectivec
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-php
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-plsql
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-python
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-ruby
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-scala_2.13
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-swift
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-visualforce
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-vm
- ${project.version}
- runtime
-
-
- net.sourceforge.pmd
- pmd-xml
+ pmd-languages-deps${project.version}
+ pomruntime
diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java
index c034682f07..452d1410fd 100644
--- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java
+++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java
@@ -75,7 +75,7 @@ public class TreeExportCommand extends AbstractPmdSubcommand {
@Option(names = "-P", description = "Key-value pair defining a property for the report format.%n"
+ "Supported values for each report format:%n${sys:pmd-cli.tree-export.report.properties.help}",
completionCandidates = TreeExportReportPropertiesCandidates.class)
- private Properties properties;
+ private Properties properties = new Properties();
@Option(names = "--file", description = "The file to parse and dump.")
private Path file;
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java
index 1d94f97c0c..1bf5e9a584 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java
@@ -558,9 +558,9 @@ public final class PmdAnalysis implements AutoCloseable {
&& configuration.getAnalysisCache() instanceof NoopAnalysisCache
&& reporter.isLoggable(Level.WARN)) {
final String version =
- PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-" + PMDVersion.VERSION;
+ PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-doc-" + PMDVersion.VERSION;
reporter.warn("This analysis could be faster, please consider using Incremental Analysis: "
- + "https://pmd.github.io/{0}/pmd_userdocs_incremental_analysis.html", version);
+ + "https://docs.pmd-code.org/{0}/pmd_userdocs_incremental_analysis.html", version);
}
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java
similarity index 98%
rename from pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java
rename to pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java
index 23235df0e0..af3d43dbf8 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java
@@ -2,7 +2,7 @@
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
-package net.sourceforge.pmd.cpd.internal;
+package net.sourceforge.pmd.cpd.impl;
import java.io.IOException;
import java.io.UncheckedIOException;
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java
similarity index 98%
rename from pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java
rename to pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java
index 083780a33a..99d44fde32 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java
@@ -2,7 +2,7 @@
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
-package net.sourceforge.pmd.cpd.internal;
+package net.sourceforge.pmd.cpd.impl;
import java.io.IOException;
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java
index edf18dbedb..6f2750966a 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java
@@ -31,7 +31,8 @@ import net.sourceforge.pmd.lang.ast.Node;
* which stores the XPath names of the generated nodes (and terminals).
*
*
Additional members can be added to a parser with {@code @parser::members { ... }}
- * in the g4 file.
+ * in the g4 file. That's how the implementations for {@link #createPmdTerminal(ParserRuleContext, Token)}
+ * and {@link #createPmdError(ParserRuleContext, Token)} can be added.
*/
public abstract class AntlrGeneratedParserBase> extends Parser {
@@ -52,9 +53,9 @@ public abstract class AntlrGeneratedParserBase> extends P
// Those two need to return a node that implements eg SwiftNode
- public abstract BaseAntlrTerminalNode createPmdTerminal(ParserRuleContext parent, Token t);
+ protected abstract BaseAntlrTerminalNode createPmdTerminal(ParserRuleContext parent, Token t);
- public abstract BaseAntlrErrorNode createPmdError(ParserRuleContext parent, Token t);
+ protected abstract BaseAntlrErrorNode createPmdError(ParserRuleContext parent, Token t);
protected Node asPmdNode(RuleContext ctx) {
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java
index 6b13d723d4..5887805ec4 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java
@@ -10,7 +10,7 @@ import java.util.List;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
-import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer;
+import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer;
import net.sourceforge.pmd.lang.ast.impl.TokenDocument;
import net.sourceforge.pmd.lang.document.TextDocument;
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java
similarity index 63%
rename from pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java
rename to pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java
index bc56f0084d..9ef6e4a472 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java
@@ -2,38 +2,31 @@
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
-package net.sourceforge.pmd.lang.ast.impl.antlr4;
+package net.sourceforge.pmd.lang.rule;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.ast.AstVisitor;
import net.sourceforge.pmd.lang.ast.Node;
-import net.sourceforge.pmd.lang.rule.AbstractRule;
-
-/**
- * Base implementation of an antlr rule.
- */
-public abstract class AntlrBaseRule extends AbstractRule {
-
- protected AntlrBaseRule() {
- // inheritance constructor
- }
+public abstract class AbstractVisitorRule extends AbstractRule {
@Override
public void apply(Node target, RuleContext ctx) {
AstVisitor visitor = buildVisitor();
assert visitor != null : "Rule should provide a non-null visitor";
- assert target instanceof AntlrNode : "Incorrect node type " + target + " passed to " + this;
- ((AntlrNode>) target).acceptVisitor(visitor, ctx);
+ target.acceptVisitor(visitor, ctx);
}
/**
* Returns a rule visitor that can visit nodes for the given rule context.
* This visitor should explore the nodes it's interested in and report
* violations on the given rule context.
+ *
+ * Language specific subclasses should redefine the return type to use
+ * a language specific visitor interface.
+ *
*
* @return A visitor bound to the given rule context
*/
public abstract AstVisitor buildVisitor();
-
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java
index 0f886bbabb..3af680f3f8 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java
@@ -39,12 +39,10 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer {
}
private static String getPmdPropertiesURL() {
+ final String BASE_URL = "https://docs.pmd-code.org/";
final String PAGE = "/pmd_userdocs_configuring_rules.html#rule-properties";
- String url = "https://pmd.github.io/pmd-" + PMDVersion.VERSION + PAGE;
- if (PMDVersion.isSnapshot() || PMDVersion.isUnknown()) {
- url = "https://pmd.github.io/latest" + PAGE;
- }
- return url;
+ final String VERSION_PART = PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-doc-" + PMDVersion.VERSION;
+ return BASE_URL + VERSION_PART + PAGE;
}
@Override
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java
index f4052818d0..39cb54baf6 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java
@@ -71,6 +71,7 @@ public class SarifRenderer extends AbstractIncrementingRenderer {
final SarifLog sarifLog = sarifLogBuilder.build();
final String json = gson.toJson(sarifLog);
writer.write(json);
+ writer.println();
}
@Override
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java
index 1367412578..8994dfcd33 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java
@@ -190,7 +190,7 @@ public class SarifLogBuilder {
return Component.builder()
.name("PMD")
.version(PMDVersion.VERSION)
- .informationUri("https://pmd.github.io/pmd/")
+ .informationUri("https://docs.pmd-code.org/latest/")
.build();
}
}
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java
index 283f39f6c3..0a0b87b385 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java
@@ -27,7 +27,7 @@ class CodeClimateRendererTest extends AbstractRendererTest {
+ "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n"
+ "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n"
+ "Description with Unicode Character U+2013: – .\\n\\n"
- + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ "Name | Value | Description\\n" + "--- | --- | ---\\n"
+ "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n"
+ "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n"
@@ -42,7 +42,7 @@ class CodeClimateRendererTest extends AbstractRendererTest {
+ "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n"
+ "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n"
+ "Description with Unicode Character U+2013: – .\\n\\n"
- + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ "Name | Value | Description\\n" + "--- | --- | ---\\n"
+ "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n"
+ "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n"
@@ -64,7 +64,7 @@ class CodeClimateRendererTest extends AbstractRendererTest {
+ "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n"
+ "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n"
+ "Description with Unicode Character U+2013: – .\\n\\n"
- + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ "Name | Value | Description\\n" + "--- | --- | ---\\n"
+ "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n"
+ "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n"
@@ -74,7 +74,7 @@ class CodeClimateRendererTest extends AbstractRendererTest {
+ "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n"
+ "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n"
+ "desc\\n\\n"
- + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n"
+ "Name | Value | Description\\n" + "--- | --- | ---\\n"
+ "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n"
+ "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n"
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json
index 91178676f0..43307fcb5f 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": []
}
},
@@ -21,4 +21,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json
index 16adc0caf0..7f467c9aab 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": []
}
},
@@ -30,4 +30,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json
index 820c78a15d..92d233a33a 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": []
}
},
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json
index 35155a5aac..3715a32406 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": []
}
},
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json
index fc2061b4e0..ca0b13614b 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": [
{
"id": "Foo",
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json
index 06f5a29a7d..b2108169d2 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": [
{
"id": "Foo",
diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json
index 3d82f299ac..a387dc1f75 100644
--- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json
+++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json
@@ -7,7 +7,7 @@
"driver": {
"name": "PMD",
"version": "unknown",
- "informationUri": "https://pmd.github.io/pmd/",
+ "informationUri": "https://docs.pmd-code.org/latest/",
"rules": [
{
"id": "Foo",
diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java
index 0728e9afbf..ccfd511bdb 100644
--- a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java
+++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java
@@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd;
import java.util.Properties;
import java.util.regex.Pattern;
-import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer;
+import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer;
import net.sourceforge.pmd.cpd.token.JavaCCTokenFilter;
import net.sourceforge.pmd.cpd.token.TokenFilter;
import net.sourceforge.pmd.lang.TokenManager;
diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java
index 64822f1a38..712fae22c3 100644
--- a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java
+++ b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java
@@ -9,7 +9,7 @@ import java.util.Properties;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
-import net.sourceforge.pmd.cpd.internal.AntlrTokenizer;
+import net.sourceforge.pmd.cpd.impl.AntlrTokenizer;
import net.sourceforge.pmd.cpd.token.AntlrTokenFilter;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager;
diff --git a/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java b/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java
index 6c847754a2..048a0a3a6f 100644
--- a/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java
+++ b/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java
@@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
-import net.sourceforge.pmd.cpd.internal.AntlrTokenizer;
+import net.sourceforge.pmd.cpd.impl.AntlrTokenizer;
import net.sourceforge.pmd.cpd.token.AntlrTokenFilter;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager;
diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml
index 554b2cb809..43bc6c06d8 100644
--- a/pmd-dist/pom.xml
+++ b/pmd-dist/pom.xml
@@ -126,7 +126,7 @@
net.sourceforge.pmd
- pmd-apex
+ pmd-core${project.version}
@@ -142,136 +142,11 @@
shcompletion
-
- net.sourceforge.pmd
- pmd-core
- ${project.version}
- net.sourceforge.pmdpmd-ant${project.version}
-
- net.sourceforge.pmd
- pmd-cpp
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-cs
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-dart
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-fortran
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-gherkin
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-go
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-groovy
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-html
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-lua
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-java
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-javascript
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-jsp
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-kotlin
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-matlab
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-modelica
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-perl
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-objectivec
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-php
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-plsql
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-python
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-ruby
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-scala_2.13
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-swift
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-tsql
- ${project.version}
- net.sourceforge.pmdpmd-ui
@@ -279,20 +154,11 @@
net.sourceforge.pmd
- pmd-visualforce
+ pmd-languages-deps${project.version}
+ pom
+ runtime
-
- net.sourceforge.pmd
- pmd-vm
- ${project.version}
-
-
- net.sourceforge.pmd
- pmd-xml
- ${project.version}
-
-
org.slf4j
diff --git a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml
index 2215aa3265..8d67eb9662 100644
--- a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml
+++ b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml
@@ -53,6 +53,19 @@
+
+
+ target/bom.xml
+ sbom
+ pmd-${project.version}-cyclonedx.xml
+
+
+ target/bom.json
+ sbom
+ pmd-${project.version}-cyclonedx.json
+
+
+
@@ -71,7 +84,9 @@
runtime
+ net.sourceforge.pmd:pmd-apex-jorje:pomnet.sourceforge.pmd:pmd-cli:sh:completion:*
+ net.sourceforge.pmd:pmd-languages-deps:pomlib0755
diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd
index 6407edb1e0..926238f9da 100755
--- a/pmd-dist/src/main/resources/scripts/pmd
+++ b/pmd-dist/src/main/resources/scripts/pmd
@@ -95,6 +95,13 @@ function script_exit() {
exit 1
}
+function check_java() {
+ java -version >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ script_exit "No java executable found in PATH"
+ fi
+}
+
determine_java_version() {
local full_ver=$(java -version 2>&1)
# java_ver is eg "80" for java 1.8, "90" for java 9.0, "100" for java 10.0.x
@@ -183,6 +190,8 @@ readonly APPNAME="${1}"
is_cygwin
+check_java
+
set_lib_dir
check_lib_dir
set_conf_dir
diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat
index f7d3fe9474..c4dc049770 100644
--- a/pmd-dist/src/main/resources/scripts/pmd.bat
+++ b/pmd-dist/src/main/resources/scripts/pmd.bat
@@ -1,19 +1,26 @@
@echo off
+rem make all variables local to not add new global environment variables to the current cmd session
+setlocal
set TOPDIR="%~dp0.."
set OPTS=
set COMMAND=%1
set MAIN_CLASS=net.sourceforge.pmd.cli.PmdCli
+rem check whether java is available at all
+java -version > nul 2>&1 || (
+ echo No java executable found in PATH
+ exit /b 1
+)
-:: sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1
-:: sets the jvendor variable to either java (oracle) or openjdk
+rem sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1
+rem sets the jvendor variable to either java (oracle) or openjdk
for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| findstr /c:"version"') do (
set jvendor=%%j
if %%l EQU ea (
set /A "jver=%%k0"
) else (
if %%k EQU 1 (
- :: for java version 1.7.x, 1.8.x, ignore the first 1.
+ rem for java version 1.7.x, 1.8.x, ignore the first 1.
set /A "jver=%%l%%m"
) else (
set /A "jver=%%k%%l"
@@ -22,11 +29,11 @@ for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| fin
)
Set "jreopts="
-:: oracle java 9 and 10 has javafx included as a module
+rem oracle java 9 and 10 has javafx included as a module
if /I %jvendor% == java (
if %jver% GEQ 90 (
if %jver% LSS 110 (
- :: enable reflection
+ rem enable reflection
SETLOCAL EnableDelayedExpansion
rem java9 and java10 from oracle contain javafx as a module
rem open internal module of javafx to reflection (for our TreeViewWrapper)
@@ -38,7 +45,6 @@ if /I %jvendor% == java (
set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED"
rem Warn of remaining illegal accesses
set "jreopts=!jreopts! --illegal-access=warn"
-
)
)
)
@@ -53,25 +59,21 @@ if [%COMMAND%] == [designer] (
if %_needjfxlib% EQU 1 (
if %jver% LSS 100 (
echo For openjfx at least java 10 is required.
- pause
- exit
+ exit /b 1
)
- if [%JAVAFX_HOME%] EQU [] (
+ if not defined JAVAFX_HOME (
echo The environment variable JAVAFX_HOME is missing.
- pause
- exit
+ exit /b 1
)
- :: The wildcard will include only jar files, but we need to access also
- :: property files such as javafx.properties that lay bare in the dir
+ rem The wildcard will include only jar files, but we need to access also
+ rem property files such as javafx.properties that lay bare in the dir
set pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%JAVAFX_HOME%\lib\*;%JAVAFX_HOME%\lib\
) else (
set pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*
)
-if [%CLASSPATH%] NEQ [] (
- set classpath=%CLASSPATH%;%pmd_classpath%
-) else (
- set classpath=%pmd_classpath%
+if defined CLASSPATH (
+ set pmd_classpath=%CLASSPATH%;%pmd_classpath%
)
java %PMD_JAVA_OPTS% %jreopts% -classpath %pmd_classpath% %OPTS% %MAIN_CLASS% %*
diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java
index c1331cbd67..25f9a8503d 100644
--- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java
+++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java
@@ -31,9 +31,10 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest {
private static final List SUPPORTED_LANGUAGES_CPD = listOf(
"apex", "cpp", "cs", "dart", "ecmascript",
"fortran", "gherkin", "go", "groovy", "html", "java", "jsp",
+ "julia",
"kotlin", "lua", "matlab", "modelica", "objectivec", "perl",
"php", "plsql", "python", "ruby", "scala", "swift", "tsql",
- "vf", "xml"
+ "typescript", "vf", "xml"
);
private static final List SUPPORTED_LANGUAGES_PMD = listOf(
@@ -87,6 +88,8 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest {
result.add(basedir + "shell/pmd-completion.sh");
result.add(basedir + "lib/pmd-core-" + PMDVersion.VERSION + ".jar");
result.add(basedir + "lib/pmd-java-" + PMDVersion.VERSION + ".jar");
+ result.add(basedir + "sbom/pmd-" + PMDVersion.VERSION + "-cyclonedx.xml");
+ result.add(basedir + "sbom/pmd-" + PMDVersion.VERSION + "-cyclonedx.json");
return result;
}
@@ -218,4 +221,13 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest {
result = CpdExecutor.runCpd(tempDir, "--minimum-tokens", "1000", "--format", "text", "--dir", srcDir);
result.assertExitCode(0);
}
+
+ @Test
+ void runAstDump() throws Exception {
+ File jumbledIncrementerSrc = new File(srcDir, "JumbledIncrementer.java");
+ List args = listOf("--format", "xml", "--language", "java", "--file", jumbledIncrementerSrc.toString());
+ ExecutionResult result = PMDExecutor.runCommand(tempDir, "ast-dump", args);
+ result.assertExitCode(0);
+ }
+
}
diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java
index 0948d9ff28..4875c560d5 100644
--- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java
+++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java
@@ -4,14 +4,8 @@
package net.sourceforge.pmd.it;
-import static net.sourceforge.pmd.util.CollectionUtil.listOf;
-
import java.nio.file.Path;
-import java.util.List;
-
-import org.apache.commons.lang3.SystemUtils;
-
-import net.sourceforge.pmd.PMDVersion;
+import java.util.Arrays;
/**
* Executes CPD from command line. Deals with the differences, when CPD is run on Windows or on Linux.
@@ -19,8 +13,6 @@ import net.sourceforge.pmd.PMDVersion;
* @author Andreas Dangel
*/
public class CpdExecutor {
- private static final String PMD_BIN_PREFIX = "pmd-bin-";
-
private CpdExecutor() {
// this is a helper class only
}
@@ -33,15 +25,6 @@ public class CpdExecutor {
* @throws Exception if the execution fails for any reason (executable not found, ...)
*/
public static ExecutionResult runCpd(Path tempDir, String... arguments) throws Exception {
- String cmd;
- List args;
- if (SystemUtils.IS_OS_WINDOWS) {
- cmd = "/bin/pmd.bat";
- } else {
- cmd = "/bin/pmd";
- }
- args = listOf("cpd", arguments);
- cmd = tempDir.resolve(PMD_BIN_PREFIX + PMDVersion.VERSION + cmd).toAbsolutePath().toString();
- return PMDExecutor.runCommand(cmd, args, null);
+ return PMDExecutor.runCommand(tempDir, "cpd", Arrays.asList(arguments));
}
}
diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java
index ccc151ddc3..22357c3eba 100644
--- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java
+++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java
@@ -36,31 +36,21 @@ public class PMDExecutor {
// this is a helper class only
}
- private static ExecutionResult runPMDUnix(Path tempDir, Path reportFile, String... arguments) throws Exception {
- String cmd = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd").toAbsolutePath().toString();
- List args = new ArrayList<>();
- args.add("check");
- args.addAll(Arrays.asList(arguments));
- return runCommand(cmd, args, reportFile);
+ static ExecutionResult runCommand(Path tempDir, String cmd, List arguments) throws Exception {
+ return runCommand(tempDir, cmd, arguments, null);
}
- private static ExecutionResult runPMDWindows(Path tempDir, Path reportFile, String... arguments) throws Exception {
- String cmd = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd.bat").toAbsolutePath().toString();
- List args = new ArrayList<>();
- args.add("check");
- args.addAll(Arrays.asList(arguments));
- return runCommand(cmd, args, reportFile);
- }
-
- static ExecutionResult runCommand(String cmd, List arguments, Path reportFile) throws Exception {
- ProcessBuilder pb = new ProcessBuilder(cmd);
-
- if (reportFile != null) {
- arguments.add(REPORTFILE_FLAG);
- arguments.add(reportFile.toString());
+ static ExecutionResult runCommand(Path tempDir, String cmd, List arguments, Path reportFile) throws Exception {
+ final String pmdScript;
+ if (SystemUtils.IS_OS_WINDOWS) {
+ pmdScript = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd.bat").toAbsolutePath().toString();
+ } else {
+ pmdScript = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd").toAbsolutePath().toString();
}
-
+ ProcessBuilder pb = new ProcessBuilder(pmdScript);
+ pb.command().add(cmd);
pb.command().addAll(arguments);
+
pb.redirectErrorStream(false);
// Ensure no ANSI output so tests can properly look at it
@@ -137,10 +127,13 @@ public class PMDExecutor {
* @throws Exception if the execution fails for any reason (executable not found, ...)
*/
public static ExecutionResult runPMD(Path reportFile, Path tempDir, String... arguments) throws Exception {
- if (SystemUtils.IS_OS_WINDOWS) {
- return runPMDWindows(tempDir, reportFile, arguments);
- } else {
- return runPMDUnix(tempDir, reportFile, arguments);
+ List args = new ArrayList<>();
+ if (reportFile != null) {
+ args.add(REPORTFILE_FLAG);
+ args.add(reportFile.toString());
}
+ args.addAll(Arrays.asList(arguments));
+
+ return runCommand(tempDir, "check", args, reportFile);
}
}
diff --git a/pmd-dist/src/test/resources/scripts/designertest.bat b/pmd-dist/src/test/resources/scripts/pmdtest.bat
similarity index 73%
rename from pmd-dist/src/test/resources/scripts/designertest.bat
rename to pmd-dist/src/test/resources/scripts/pmdtest.bat
index d43a5ff146..40f189ce7a 100644
--- a/pmd-dist/src/test/resources/scripts/designertest.bat
+++ b/pmd-dist/src/test/resources/scripts/pmdtest.bat
@@ -1,27 +1,27 @@
@echo off
-:: BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+rem BSD-style license; for more info see http://pmd.sourceforge.net/license.html
-::
-:: Simple manual test script
-:: - code is copied from designer.bat to be tested here (so please check, it might be out of sync)
-:: - mostly the function "determine_java_version" is tested here
-:: - just run it with "designertest.bat" and look at the output
-:: - test cases are at the end of this script
-::
+rem
+rem Simple manual test script
+rem - code is copied from pmd.bat to be tested here (so please check, it might be out of sync)
+rem - mostly the function "determine_java_version" is tested here
+rem - just run it with "pmd.bat" and look at the output
+rem - test cases are at the end of this script
+rem
GOTO :main
:determine_java_version
-:: sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1
-:: sets the jvendor variable to either java (oracle) or openjdk
+rem sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1
+rem sets the jvendor variable to either java (oracle) or openjdk
for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in (%full_version%) do (
set jvendor=%%j
if %%l EQU ea (
set /A "jver=%%k0"
) else (
if %%k EQU 1 (
- :: for java version 1.7.x, 1.8.x, ignore the first 1.
+ rem for java version 1.7.x, 1.8.x, ignore the first 1.
set /A "jver=%%l%%m"
) else (
set /A "jver=%%k%%l"
@@ -67,6 +67,24 @@ if [%detection%] == [] (
EXIT /B
+:check_for_java_command
+set cmd=%1
+echo cmd=%1
+%cmd% -version > nul 2>&1 || (
+ echo No java executable not found in PATH
+ EXIT /B 1
+)
+EXIT /B 0
+
+:check_classpath_extension
+setlocal
+set cp=%1
+echo testing cp=%1
+if defined cp (
+ echo classpath is not empty
+)
+endlocal
+EXIT /B
:run_test
set full_version=%1
@@ -86,6 +104,16 @@ EXIT /B
:main
+CALL :check_for_java_command javanotfound
+echo errorlevel: %ERRORLEVEL%
+
+CALL :check_classpath_extension
+CALL :check_classpath_extension a\b.jar
+CALL :check_classpath_extension "a\b.jar;c\d.jar"
+CALL :check_classpath_extension "a\b.jar"
+CALL :check_classpath_extension "a"\b.jar
+CALL :check_classpath_extension "a"\b.jar;"c"\d.jar
+
CALL :run_test "java version ""1.7.0_80""" java 70 "detected java 7"
CALL :run_test "openjdk version ""1.7.0_352""" openjdk 70 "detected java 7"
CALL :run_test "java version ""1.8.0_271""" java 80 "detected java 8"
diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java
index fd9d03a244..1bbe22cf51 100644
--- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java
+++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java
@@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.gherkin.cpd;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
-import net.sourceforge.pmd.cpd.internal.AntlrTokenizer;
+import net.sourceforge.pmd.cpd.impl.AntlrTokenizer;
import net.sourceforge.pmd.lang.gherkin.ast.GherkinLexer;
/**
diff --git a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java
index 98d2653f85..d46d4827ed 100644
--- a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java
+++ b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java
@@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
-import net.sourceforge.pmd.cpd.internal.AntlrTokenizer;
+import net.sourceforge.pmd.cpd.impl.AntlrTokenizer;
import net.sourceforge.pmd.lang.go.ast.GolangLexer;
public class GoTokenizer extends AntlrTokenizer {
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java
index 525d1731b2..a1ac11bfc8 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java
@@ -9,7 +9,7 @@ import java.util.Deque;
import java.util.LinkedList;
import java.util.Properties;
-import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer;
+import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer;
import net.sourceforge.pmd.cpd.token.JavaCCTokenFilter;
import net.sourceforge.pmd.cpd.token.TokenFilter;
import net.sourceforge.pmd.lang.TokenManager;
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java
index f3e9e4a253..6eafbbb05a 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java
@@ -4,8 +4,8 @@
package net.sourceforge.pmd.lang.java.rule.codestyle;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -35,7 +35,9 @@ public class UnnecessaryConstructorRule extends AbstractIgnoredAnnotationRule {
@Override
protected Collection defaultSuppressionAnnotations() {
- return Collections.singletonList("javax.inject.Inject");
+ return Arrays.asList("javax.inject.Inject",
+ "com.google.inject.Inject",
+ "org.springframework.beans.factory.annotation.Autowired");
}
@Override
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java
index ecd65ef8b6..759032dc0f 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java
@@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.design;
import static net.sourceforge.pmd.util.CollectionUtil.setOf;
-import java.util.List;
import java.util.Set;
import net.sourceforge.pmd.lang.ast.NodeStream;
@@ -25,27 +24,25 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule;
import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass;
import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.AssignmentEntry;
import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.DataflowResult;
-import net.sourceforge.pmd.lang.java.rule.internal.JavaPropertyUtil;
-import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.util.CollectionUtil;
public class ImmutableFieldRule extends AbstractJavaRulechainRule {
- private static final PropertyDescriptor> IGNORED_ANNOTS =
- JavaPropertyUtil.ignoredAnnotationsDescriptor();
-
private static final Set INVALIDATING_CLASS_ANNOT =
setOf(
"lombok.Builder",
"lombok.Data",
- "lombok.Getter",
"lombok.Setter",
"lombok.Value"
);
+ private static final Set INVALIDATING_FIELD_ANNOT =
+ setOf(
+ "lombok.Setter"
+ );
+
public ImmutableFieldRule() {
super(ASTFieldDeclaration.class);
- definePropertyDescriptor(IGNORED_ANNOTS);
}
@@ -55,7 +52,7 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule {
if (field.getEffectiveVisibility().isAtMost(Visibility.V_PRIVATE)
&& !field.getModifiers().hasAny(JModifier.VOLATILE, JModifier.STATIC, JModifier.FINAL)
&& !JavaAstUtils.hasAnyAnnotation(enclosingType, INVALIDATING_CLASS_ANNOT)
- && !JavaAstUtils.hasAnyAnnotation(field, getProperty(IGNORED_ANNOTS))) {
+ && !JavaAstUtils.hasAnyAnnotation(field, INVALIDATING_FIELD_ANNOT)) {
DataflowResult dataflow = DataflowPass.getDataflowResult(field.getRoot());
@@ -82,9 +79,9 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule {
if (!hasWrite && !isBlank) {
//todo this case may also handle static fields easily.
- addViolation(data, varId, varId.getName());
+ asCtx(data).addViolation(varId, varId.getName());
} else if (hasWrite && defaultValueDoesNotReachEndOfCtor(dataflow, varId)) {
- addViolation(data, varId, varId.getName());
+ asCtx(data).addViolation(varId, varId.getName());
}
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java
index c5c070249a..66741473a1 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java
@@ -36,6 +36,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTContinueStatement;
import net.sourceforge.pmd.lang.java.ast.ASTDoStatement;
+import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant;
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
@@ -954,6 +955,7 @@ public final class DataflowPass {
@Override
public SpanInfo visitTypeDecl(ASTAnyTypeDeclaration node, SpanInfo data) {
+ // process initializers and ctors first
processInitializers(node.getDeclarations(), data, node.getSymbol());
for (ASTBodyDeclaration decl : node.getDeclarations()) {
@@ -989,12 +991,14 @@ public final class DataflowPass {
for (ASTBodyDeclaration declaration : declarations) {
final boolean isStatic;
- if (declaration instanceof ASTFieldDeclaration) {
+ if (declaration instanceof ASTEnumConstant) {
+ isStatic = true;
+ } else if (declaration instanceof ASTFieldDeclaration) {
isStatic = ((ASTFieldDeclaration) declaration).isStatic();
} else if (declaration instanceof ASTInitializer) {
isStatic = ((ASTInitializer) declaration).isStatic();
} else if (declaration instanceof ASTConstructorDeclaration
- || declaration instanceof ASTCompactConstructorDeclaration) {
+ || declaration instanceof ASTCompactConstructorDeclaration) {
ctors.add(declaration);
continue;
} else {
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java
index d8ccc72e28..f3a35f4361 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java
@@ -46,6 +46,23 @@ public final class TestFrameworksUtil {
"junit.framework.Assert",
"junit.framework.TestCase");
+ private static final Set TEST_CONFIGURATION_ANNOTATIONS =
+ setOf("org.junit.Before",
+ "org.junit.BeforeClass",
+ "org.junit.After",
+ "org.junit.AfterClass",
+ "org.testng.annotations.AfterClass",
+ "org.testng.annotations.AfterGroups",
+ "org.testng.annotations.AfterMethod",
+ "org.testng.annotations.AfterSuite",
+ "org.testng.annotations.AfterTest",
+ "org.testng.annotations.BeforeClass",
+ "org.testng.annotations.BeforeGroups",
+ "org.testng.annotations.BeforeMethod",
+ "org.testng.annotations.BeforeSuite",
+ "org.testng.annotations.BeforeTest"
+ );
+
private TestFrameworksUtil() {
// utility class
}
@@ -75,10 +92,7 @@ public final class TestFrameworksUtil {
* Returns true if this is a Before/setUp method or After/tearDown.
*/
public static boolean isTestConfigurationMethod(ASTMethodDeclaration method) {
- return method.isAnnotationPresent("org.junit.Before")
- || method.isAnnotationPresent("org.junit.BeforeClass")
- || method.isAnnotationPresent("org.junit.After")
- || method.isAnnotationPresent("org.junit.AfterClass")
+ return TEST_CONFIGURATION_ANNOTATIONS.stream().anyMatch(method::isAnnotationPresent)
|| isJUnit3Class(method.getEnclosingType())
&& ("setUp".equals(method.getName())
|| "tearDown".equals(method.getName()));
diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml
index c888a021ff..ac2a1558e0 100644
--- a/pmd-java/src/main/resources/category/java/errorprone.xml
+++ b/pmd-java/src/main/resources/category/java/errorprone.xml
@@ -2349,7 +2349,7 @@ See the property `annotations`.